1

Using PrimeNG DynamicDialog, I'm trying to create a consistent header-content-footer layout for all the dialogs in my use case. When opening a custom dialog component, in the dialog configuration, there's a property called templates. I could successfully create custom header and footer components by specifying header and footer properties. For content too, I would like certain common elements enforced in all custom dialogs e.g. loading indicator, loading message, border etc. I planned to do this by using NgComponentOutlet to render the custom dialog component dynamically. However, when I specify the content property, the dialog doesn't render the custom dialog component properly and throws an undefined error described further below.

DynamicDialogConfig

{
 // other properties
 templates: {
 footer: Footer,
 content: BaseContent,
 },
}

BaseContent definition

@Component({
 selector: 'base-content',
 standalone: true,
 imports: [CommonModule],
 template: `
 <div class="card">
 <ng-container *ngComponentOutlet="projectedComponent"></ng-container>
 </div> `,
})
export class BaseContent implements OnInit {
 projectedComponent = null;
 constructor(public ref: DynamicDialogRef) {}
 async ngOnInit() {
 this.projectedComponent = await firstValueFrom(
 this.ref.onChildComponentLoaded
 );
 }
}

Undefined error

On debugging, I found that it errors out when loadChildComponent() is called. More specifically, the insertionPoint is undefined.

source

Minimum reproducible example:

PrimeNG DynamicDialog - content template

Is something wrong with the design ? or with the usage of content property ?

Naren Murali
65.9k6 gold badges50 silver badges96 bronze badges
asked Oct 25 at 9:43

1 Answer 1

1

The template content replaces the component contents, hence it is blank.

Instead pass in the content component ( which contains the reusable stuff ) into the dialog service open method.

show() {
 this.ref = this.dialogService.open(BaseContent, {
 header: 'Product List',
 width: '50vw',
 modal: true,
 contentStyle: { overflow: 'auto' },
 breakpoints: {
 '960px': '75vw',
 '640px': '90vw',
 },
 data: {
 component: ProductListDemo,
 },
 templates: {
 footer: Footer,
 // content: BaseContent,
 },
 });

We then pass in the component to be shown as a data property, we can render this in the content component.

import { Component, inject } from '@angular/core';
import { DynamicDialogConfig } from 'primeng/dynamicdialog';
import { CommonModule } from '@angular/common';
@Component({
 selector: 'base-content',
 standalone: true,
 imports: [CommonModule],
 template: `
 <div class="card">
 @if(projectedComponent) {
 <ng-container *ngComponentOutlet="projectedComponent"></ng-container>
 }
 </div> `,
})
export class BaseContent {
 projectedComponent = null;
 dynamicDialogConfig = inject(DynamicDialogConfig);
 ngOnInit() {
 this.projectedComponent = this.dynamicDialogConfig.data.component;
 }
}

Stackblitz Demo

answered 2 days ago
Sign up to request clarification or add additional context in comments.

1 Comment

This works, is there any other way of passing component type besides via config data. Because I'm using config data to send custom data in to the component being opened.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.