Home > Software engineering >  Angular's createComponent API doesn't work when a component render data
Angular's createComponent API doesn't work when a component render data

Time:01-21

I'm trying to create a ModalService that inserts a modal into document's body. Basically my solution works, but only if the content of the modal is the static HTML. If I'm trying to render some data in the modal, then nothing is displayed

ModalService:

@Injectable({
  providedIn: 'root',
})
export class ModalService {
  constructor(
    private appRef: ApplicationRef,
    private injector: EnvironmentInjector
  ) {}

  open(modalBodyType: Type<ElementRef>) {
    const modalContentRef = createComponent(modalBodyType, {
      environmentInjector: this.injector,
    });

    const modalRef = createComponent(ModalComponent, {
      environmentInjector: this.injector,
      projectableNodes: [
        // 1st <ng-content>
        [modalContentRef.location.nativeElement],
      ],
    });

    document.body.appendChild(modalRef.location.nativeElement);
    this.appRef.attachView(modalRef.hostView);
  }
}

and I'm trying to display this component with that service:

@Component({
  standalone: true,
  template: `Hello`, // this WORKS

  // the line below DOESN'T work
  // template: `Hello {{ name }}!`,
})
export class HelloComponent {
  name = 'Angular';
}

if I uncomment the template that renders name, then nothing is displayed What am I doing wrong?

demo on stackblitz

CodePudding user response:

You need to trigger the change detection on the projected component for it to evaluate its declarations !

  open(modalBodyType: Type<ElementRef>) {
    const modalContentRef = createComponent(modalBodyType, {
      environmentInjector: this.injector,
    });

    const modalRef = createComponent(ModalComponent, {
      environmentInjector: this.injector,
      projectableNodes: [
        // 1st <ng-content>
        [modalContentRef.location.nativeElement],
      ],
    });

    modalContentRef.changeDetectorRef.detectChanges() // here ! 
    document.body.appendChild(modalRef.location.nativeElement);
    this.appRef.attachView(modalRef.hostView);
  }
  • Related