Load generic angular dynamic component

298 Views Asked by At

I am trying to make a dynamic component for the popup to create view and edit page for different content. I have made a popup component in which I want to pass a new component name and title of the page. However, I am not getting new component data in the popup component. Please have a look at code, if you need any more detail, please ask. Thanks in Advance.

I have tried to inject service in another component and it gets data on button click, but in the popup component, I am not getting data. For now, I am doing just console.log data to popup.component.ts file but there is no result in console.log.

folder structure for the dynamic popup component

popup.service.ts

export class PopupService {
    isShowing = false;
    private popup = new Subject();
    loadingPopup = new Subject();
    outputEmitter = new Subject();
    popupContent: any = {
        isShowing: false,
        content: null,
        contentParams: PopupModel
    }
    constructor() { }
    public getPopup() {
        return this.popup;
    }
    public showLoading(isLoading: boolean = true) {
        this.loadingPopup.next(isLoading);
    }
    public create(component: any, parameters?: PopupModel): any {     
        this.showLoading(true);
        this.popupContent.isShowing = true;
        this.popupContent.content = component;
        this.popupContent.contentParams = parameters;
        this.popup.next(this.popupContent);
        console.log(this.popupContent)
    }
}

Popupcomponent.ts

export class PopupComponent implements OnInit, OnDestroy {

public popupObservable: Subscription;

constructor(private popupService: PopupService) { }

ngOnInit() {
this.popupObservable = this.popupService.getPopup().subscribe((popupContent: any) => {
console.log(popupContent)
//code here to use createDynamicComponent method }
}
private createDynamicComponent(component: Type<any>): void {
//code here using ComponentFactoryResolver and ViewContainerRef to create dynamic component
}
ngOnDestroy() {
    if (this.popupObservable && !this.popupObservable.closed) {
      this.popupObservable.unsubscribe();
    }
  }
}

This is the code where the dynamic component is being called and the popup should be created. Component.ts

AddRecord(){
    this.popupService.create( NewRecordComponent, {
      title: 'Add',
      emitterMethod: 'saved'
    })
  }

component.html

<button (click)="AddRecord()">Add</button>
1

There are 1 best solutions below

2
On

You are not emitting a value from your subject anywhere.
You would need to call popup.next(popupContent).

However, I don't think you have the right model here.
If you're not doing any async calls (api, filesystem etc..) in your getPopup method, then just return the popupContent directly

public getPopup() : {} {
        return this.popupContent;
    } 

You should also define an interface for your popupContent somewhere so you can import it and use a strong interface to avoid runtime errors.

e.g.

export interface IPopupContent {
  isShowing: boolean;
  content: string;
  contentParams: PopupModel;
}

Also, don't expose subjects directly, rather expose an observable linked to the subject.

See When to use asObservable() in rxjs?