jitenderd
jitenderd

Reputation: 198

Migrating Angular material dialog to 17 and componentfactory deprecation in Angular

In Angular 13 i was creating a _bodyComponent using the _injectDialogHost() Method as below:

    private _injectDialogHost(): void {
            const componentFactory = this._componentFactoryResolver.resolveComponentFactory(this.data?.component);
            this._bodyComponent = this._dialogHost?.viewContainerRef?.createComponent(componentFactory, 0, this._createInjector());
            this._bodyComponent?.changeDetectorRef?.detectChanges();
        }

In Angular 17, I updated this method as _componentFactoryResolver is deprecated:

 private _injectDialogHost(): void {
        this._bodyComponent = this._dialogHost?.viewContainerRef?.createComponent(this.data?.component);
        this._bodyComponent?.changeDetectorRef?.detectChanges();
    }

In the this.data?.component, I an injecting DIALOG_DATA which is created using an InjectionToken

const ALLOY_DIALOG_DATA = new InjectionToken<any>('DialogData');

constructor(
        @Inject(DIALOG_DATA) public data: IDialogData,
        private elRef: ElementRef,
        private renderer: Renderer2,
    ) {
        if (this.data?.dialogRef?.componentInstance?.dialogConfig?.resizable === true) {}}

The issue now is that my dialogRef is undefined now which was there in matlegacy.

Now this.data is giving me an InjectionToken and not an Object containing content and dialogRef as it used to give in earlier version of Angular and material.

Any pointer how can i get that dialogRef again so that my code is working as it was used to? SS for reference below: enter image description here

Upvotes: -1

Views: 766

Answers (2)

jitenderd
jitenderd

Reputation: 198

The issue here was that Injector was not passed in the parameters of createComponent. I created an injector function to do so and code was working.

private _createInjector(): Injector {
        const data = { dialogRef: this._dialogRef, content: this.data?.content };
        return Injector.create({
            providers: [{ provide: DIALOG_DATA, useValue: data }]
          });
    }

    private _injectDialogHost(): void {
        this._bodyComponent = this._dialogHost?.viewContainerRef?.createComponent(this.data?.component, {injector:this._createInjector()});
        this._bodyComponent?.changeDetectorRef?.detectChanges();
    }

Upvotes: 0

rkristof
rkristof

Reputation: 59

You can try to inject MatDialogRef instead of IDialogData.

import { MatDialogRef } from '@angular/material/dialog';
    
constuctor(private readonly dialogRef: MatDialogRef) {}

Also in the documentation you can find some extra info: MatDialogRef

Upvotes: 0

Related Questions