Error No component factory found for ... in Ionic 4

Viewed 5258

I have a ModalComponent

if I declare it like so in my app.module.ts It works fine and I can use it in my app.

@NgModule({
  declarations: [AppComponent, ModalComponent],
  entryComponents: [ModalComponent],
  ...
})

Now If I do the same in a my page page.module.ts and try to use the modal there it doesn't work. Why?

I get this error No component factory found for ... yadaayaydayada

I've read this could be outdated scripts issue because of ionic 4, so I made sure my package.json base is identical to their templates.

My ideal solution would be to display the modal from a component within a page, but I can't get it to work due to the above error.

How do I need to register my component so I can bind it programmatically within a page and/or inside a component nested in that page?

More Information Below

This is how I display my modal:

async presentModal() {
  const modal = await this.ui.modalController.create({
    component: ModalComponent,
  });

  return await modal.present();
}
  • My nested component & modal component don't have @NgModule's

Complete app.module.ts

//Omitting Imports

@NgModule({
  declarations: [AppComponent, ModalComponent],
  entryComponents: [ModalComponent],
  imports: [
    BrowserModule,
    HttpModule,
    FormsModule,
    HttpClientModule,
    OAuthModule.forRoot(),
    IonicModule.forRoot(),
    AppRoutingModule, // <-- This is where the Page is imported
  ],
  providers: [
    OAuthService,
    UrlHelperService,
    InAppBrowser,
    StatusBar,
    SplashScreen,
    Camera,
    WebView,
    File,
    FileTransfer,
    VideoEditor,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    { provide: HTTP_INTERCEPTORS, useClass: UnAuthorizedService, multi: true, }
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Here is my app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: '', loadChildren: './battles/tabs/tabs.module#TabsPageModule' }, <-- page registered here
   //omitting other routes
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Here is my tabs.router.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';

import { TabsPage } from './tabs.page';

const routes: Routes = [
  {
    path: 'battles',
    component: TabsPage,
    children: [
      {
        path: 'user',
        children: [
          {
            path: '',
            loadChildren: '../user/user.module#UserPageModule' <-- Here is my page (I think this might be lazy loaded not sure.)
          }
        ]
      }
      //Omitting other routes
    ]
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class TabsPageRoutingModule { }

Here is the page.module

import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';

import { IonicModule } from '@ionic/angular';

import { UserPage } from './user.page';

const routes: Routes = [
  {
    path: '',
    component: UserPage
  }
];

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    IonicModule,
    RouterModule.forChild(routes)
  ],
  declarations: [UserPage],
  // I would declare my modal like this same as in the app.module, 
  // but this isn't working, for now I'm storing it in app.module
  //    declarations: [UserPage, ModalComponent],
  //    entryComponents: [ModalComponent],

})
export class UserPageModule { }

Full Error:

ERROR Error: Uncaught (in promise): Error: No component factory found for ModalComponent. Did you add it to @NgModule.entryComponents?

I think because my page is lazy loaded I am facing this issue which my lack of Angular knowledge stops me from understanding how to solve it.

2 Answers

This Answere is from "razmans" in the Ionic FrameWork Forum

Import into app.module.ts first the PageModule and then only you can import into Home.

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouterModule, RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {FirstPageModule} from './first/first.module'


@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule,FirstPageModule],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

home.ts

import { Component } from '@angular/core';
import { NavController,AlertController,ModalController } from '@ionic/angular';
import {FirstPage} from '../first/first.page';


@Component({
  selector: 'app-page-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss']
})
export class HomePage {
  constructor( private modalCtrl:ModalController,private alertCtrl:AlertController) {}

  async moveToFirst()
  {
    const modal = await this.modalCtrl.create({
     component: FirstPage
   });

   return await modal.present();
  }
}

This will open my modal. Closing it is a whole other thing, instead of getting ViewController to do it, you need to get ModalController to do it with this.modalCtrl.dismiss. Here’s how I closed the modal from first.page.ts

import { Component, OnInit } from '@angular/core';
import { NavController,ModalController } from '@ionic/angular';


@Component({
  selector: 'first',
  templateUrl: './first.page.html',
  styleUrls: ['./first.page.scss'],
})
export class FirstPage implements OnInit {

  constructor(private nav:NavController,private modalCtrl:ModalController) {}

  ngOnInit() {
  }

  closeModal()
  {
    this.modalCtrl.dismiss();
  }

Just import modal page module into imports array of your app.module.ts

app.module.ts

    import { NgModule } from '@angular/core';
    import { ModalPageModule } from './modal/modal.module';

    imports: [ ..., ModalPageModule]

Then in your page that requires the modal, import the modal page itself and ModalController

modal.page

    import { ModalController } from '@ionic/angular';
    import { ModalPage } from '../modal/modal.page';

    @Component({
    selector: ...,
    templateUrl: ...,
    styleUrls: ...,
    })

    export class MyPageThatRequiresModal implements OnInit {

    constructor(public modalController: ModalController) { }

    ...

     async presentModal() {
      const modal = await this.modalController.create({
        component: ModalPage,
        componentProps: { value: 123 }
     });

     return await modal.present();

    }

    ...


    }
Related