Miguel Moura
Miguel Moura

Reputation: 39364

Simple ModalService for Angular 7 does not open: No component factory found for

I am creating an Angular's 7 ModalService that simply opens a Modal (StackBlitz Example).

The Modal content should be a Component passed to the Modal when opening.

Modal

export class Modal {

  protected modal: any = null;

  close() {
    this.modal.close();
  }

}

ModalService

import { ApplicationRef, ComponentFactoryResolver, EmbeddedViewRef, Injectable, Injector } from '@angular/core';

@Injectable({
  providedIn: 'root'
})

export class ModalService {

  private componentRef: any;
  private modalContainer: any;

  constructor(
    private componentFactoryResolver: ComponentFactoryResolver,
    private appRef: ApplicationRef,
    private injector: Injector) { }

  private createFormModal(component: any): Element {

    this.componentRef = this.componentFactoryResolver.resolveComponentFactory(component.component).create(this.injector);

    this.componentRef.instance.modal = this;

    this.appRef.attachView(this.componentRef.hostView);

    return (this.componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
  }

  open(component: any): void {

    const alertElement = this.createFormModal(component);

    const content = document.createElement('div');
    content.classList.add('modal');
    content.appendChild(alertElement);

    this.modalContainer = document.createElement('div');
    this.modalContainer.classList.add('modal');
    this.modalContainer.appendChild(content);

    document.body.appendChild(this.modalContainer);

  }

  close(): void {
    this.appRef.detachView(this.componentRef.hostView);
    this.modalContainer.parentNode.removeChild(this.modalContainer);
    this.componentRef.destroy();
  }

}

I am not sure if this is the best option but it is not working ...

When I try to open the modal I get the following error:

Error: No component factory found for HelloComponent. 
       Did you add it to  Did you add it to @NgModule.entryComponents?

What am I missing? And can I improve this ModalService code?

Upvotes: 2

Views: 3191

Answers (2)

user11024540
user11024540

Reputation: 11

Add HelloComponent in entry component of @NgModule:

@NgModule({
     imports:[ BrowserModule, FormsModule ],
     declarations:[ AppComponent, HelloComponent ],
      entryComponents:[HelloComponent],
      bootstrap: [ AppComponent ]
 })

 export class AppModule { }

Upvotes: 1

Niladri
Niladri

Reputation: 5962

As the error suggests , you need to add the component in the entryComponentsarray of your root module app.module.ts if you need to render the component as the modal content. This is required because as per the angular documentation if you are dynamically loading a component by type imperatively(using ComponentFactoryResolver) then you need to add that component in the entryComponentsarray of your root module. Because these components are not referenced in your angular app by template or by selector.

So your app.module.ts should look like this -

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, HelloComponent ],
  entryComponents:[HelloComponent],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

Here is the updated stackblitz demo -

https://stackblitz.com/edit/mk-angular-modal-service-6qhrps

Here is more information on entryComponents

https://angular.io/guide/entry-components

There are still some css issue in your modal which needs to be fixed.

Upvotes: 6

Related Questions