Home > OS >  ComponentFactoryResolver and AbstractControlDirective after update angular to v14
ComponentFactoryResolver and AbstractControlDirective after update angular to v14

Time:11-09

I update angular from v9 to v14 and now I get error with ComponentFactoryResolver and AbstractControlDirective

Here is my directive.ts

  private componentRef: ComponentRef<FormErrorComponent>;
  private ngControl: NgControl;
  private unsubscribe$ = new Subject();

constructor(
    private viewContainerRef: ViewContainerRef,
    private componentFactoryResolver: ComponentFactoryResolver,
    private formField: MatFormField,
    private elRef: ElementRef,
    private injector: Injector
  ) { }

  ngAfterViewInit() {
    this.ngControl = this.formField._control.ngControl;
            
            |
    Error for ngControl: Type 'NgControl | AbstractControlDirective' is not assignable to type 'NgControl'.
    Type 'AbstractControlDirective' is missing the following properties from type 
    'NgControl': name, valueAccessor, viewToModelUpdatets(2322)
  

    this.ngControl.statusChanges.pipe(
      takeUntil(this.unsubscribe$)
    ).subscribe(_ => this.handleStatusChange());
  }

I try create getter for control but not working

get control() {
     return this.ngControl.control as FormControl;
   }

And call it after we set ngControl

this.control.statusChanges.pipe(
          takeUntil(this.unsubscribe$)
        ).subscribe(_ => this.handleStatusChange());

And also for ComponentFactoryResolver, how to handle this in version 14?

private componentRef: ComponentRef<FormErrorComponent>;

  constructor(
    private componentFactoryResolver: ComponentFactoryResolver, -> @deprecated
Angular no longer requires Component factories. Please use other APIs where Component class can be used directly.

'ComponentFactoryResolver' is deprecated.ts(6385)
  ) { }


private addErrors(errors: Object) {
    const host = this.elRef.nativeElement.querySelector('.mat-form-field-subscript-wrapper');
    const factory = this.componentFactoryResolver.resolveComponentFactory(FormErrorComponent);

    this.componentRef = factory.create(this.injector, [], host);

    this.componentRef.instance.errors = errors;

    this.componentRef.changeDetectorRef.detectChanges();
  }

Thnx

CodePudding user response:

With a target div declared like this :

@ViewChild("container", { read: ViewContainerRef, static: true }) container!: ViewContainerRef;`

You can call

  const componentRef = this.container.createComponent(component, { injector: this.injector);
  • Related