Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ts-mixer with Angular #47

Open
Nxtivision opened this issue Jun 21, 2022 · 2 comments
Open

Ts-mixer with Angular #47

Nxtivision opened this issue Jun 21, 2022 · 2 comments
Labels
question Further information is requested

Comments

@Nxtivision
Copy link

Nxtivision commented Jun 21, 2022

Hello,

Thank you for this nice library, it seems to be very interesting to use for our use cases.

However, I'm not able to use it properly in Angular. Here is an example :

// Global config for ts-mixer :

import { settings } from 'ts-mixer';

settings.prototypeStrategy = 'proxy';
settings.staticsStrategy = 'proxy';

export default settings;
// Component receiving all extending classes
@Component({
  selector: 'one-forms-input-text',
  templateUrl: './text.component.html',
  styles: [],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: TextComponent,
      multi: true,
    },
  ],
})
export class TextComponent extends Mixin(
  LengthValidatorTemplateMixin,
  ControlValueAccessorConnector
) {
  /**
   * Used to implement a CSS class directly on the host
   * @internal
   * @protected
   */
  @decorate(HostBinding('class.one-forms-input-text'))
  protected override hostClass = true;

  /**
   * Suffix icon to display
   */
  @decorate(Input())
  icon: MaterialIcon = '';

  constructor(injector: Injector) {
    super(injector);
  }
}
export class ControlValueAccessorConnector implements ControlValueAccessor {
  /** Default class applied on Host element */
  @decorate(HostBinding('class.one-forms-input'))
  protected hostClass = true;

  /** Update user-select CSS property */
  @decorate(HostBinding('style.user-select'))
  protected userSelectMode = 'auto';
  /**
   * Used to implement the display CSS property directly on the host
   *
   * @protected
   */
  @decorate(HostBinding('style.display')) protected hostDisplay =
    'inline-block';
  /**
   * @internal
   *
   * used internally to manage the form control
   */
  @decorate(ViewChild(FormControlDirective, { static: true }))
  formControlDirective: FormControlDirective | undefined;

  /**
   * First way to set the formControl by using the formControl itself
   */
  @decorate(Input())
  formControl: FormControl | undefined;

  /**
   * Another way to set the formControl by using the formControlName
   */
  @decorate(Input())
  formControlName = '';

  /**
   * Placeholder of the input, when there is no user input
   */
  @decorate(Input())
  placeholder = '';

  /**
   * Label to name the input
   */
  @decorate(Input())
  label = '';

  /**
   * Add without-label class to the host component if no label specified
   * @protected
   */
  @decorate(HostBinding('class.without-label'))
  protected get hostWithoutLabel() {
    return this.label === '';
  }

  /**
   * The message to describe the input by setting the mat-hint
   */
  @decorate(Input())
  description = '';

  constructor(private injector: Injector) {}
export class LengthValidatorTemplateMixin {
  /**
   * Minimum length for the input
   */
  @decorate(Input()) minLength: string | number | null = null;

  /**
   * Maximum length for the input
   */
  @decorate(Input()) maxLength: string | number | null = null;
}

The error thrown is:
Error: Cannot set new properties on Proxies created by ts-mixer

After some investigation, it seems there is a problem with the constructor:
2022-06-21_15h49_28

Do you have any idea how I could use ts-mixer in Angular properly?

Thank you and have a nice day

@tannerntannern
Copy link
Owner

Hi @Nxtivision, the first thing I'm curious about is whether it's necessary to use ts-mixer's proxy settings in your case. I can't say for certain without doing a deep dive, but I'd guess Angular's dependency injection mechanisms could cause problems with those proxy settings.

Also before I can dive deeper I'll need a minimal reproducible example, preferably as a repository I can clone and recreate the error. There are too many unknowns with your example code (TypeScript/Angular/ts-mixer versions, compilation settings, just to name a few) for me to reproduce or even know for sure whether ts-mixer is the root of the problem.

Please note that I have limited time to support this library, so focused and complete examples are crucial for me to be able to troubleshoot. Thank you for understanding.

@tannerntannern tannerntannern added the question Further information is requested label Jun 22, 2022
@hakimio
Copy link
Contributor

hakimio commented Sep 27, 2022

The library works well with the latest version of Angular (14) when you use default prototype strategy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants