RC0 No component factory found for ComponentA

My app has ComponentA which is a Form. This form is used for creating a new item and to edit an item.

The weird thing is from PageA I can navigate without any problem to ComponentA. But PageB triggers the error:

error_handler.js:47 ORIGINAL EXCEPTION: No component factory found for ComponentA

What could possibly cause PageA to work but PageB to raise an error? Both pages use exactly the same instruction:

this.nav.push(ComponentA);

Make sure you page is also declared in the app.module

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { Test } from '../pages/test/test';

@NgModule({
  declarations: [
    MyApp,
    HomePage,
    Test
  ],
  imports: [
    IonicModule.forRoot(MyApp)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
    Test
  ],
  providers: []
})
export class AppModule { }

Pages need to be declared in the declarations and entryComponents

36 Likes

ComponentA is indeed declared in both sections.

I also removed the .tmp folder to be sure there was no remaining data and rebuild.

What I can’t understand is why one page knows ComponentA and another doesn’t recognise it.

Another observation:
I’ve copied the template from ComponentA to ComponentB.

Then I linked PageA to ComponentA and PageB to ComponentB then the error does not occur.

This exact same thing happen to me when I use Tabs.This was after creating a blank project. When I create a tabs starter it runs fine

It looks like I’ve fixed it for now. In the Beta12 I’ve got the same problem, but copying the file to another name e.g. ComponentA.ts to ComponentAEdit.ts made it work.

After hours of searching I saw that PageA referred to ComponentA with:

../pages/ComponentA

and ComponentB uses:

../Pages/ComponentB

(notice the case difference) I am working on OSX and making the path case consistent solved my problem.

I have similar weird problem. After renaming components , it works

1 Like

So all pages need to be under declarations & entryComponents? I might as well make an object out of it right?

1 Like

Hi,

could please some Angular2 expert shed some light on this, why I have to define ALL Components of my project in entryComponents property?

As far as I understand for AoT compiling (Ahead Of Time) the compiler needs to know all components you are going to use. When using JIT compiling (Just In Time), the components don’t need to be known beforehand. When you enter a page it looks at your imports and checks the relations on the fly accordingly (please correct me if I’m wrong :slight_smile: )

OK, I understand. And this should improve performance drastically right?

Indeed, you can see it this way: JIT has no clue what might be needed from all your included libraries including Angular. Therefore everything needs to be loaded since the compiler only knows what is needed “just in time”.

With AoT everything is compiled beforehand, so the compiler knows exactly what you used in your app. Everything else can be “thrown away” which drastically reduces the size of your compiled code.

Besides AoT does a lot op optimalisation steps, think about template compiling etc. Explained simple: A JIT compiler need to iterate over all DOM elements to see if there are Angular statements. This takes a lot of time. With AoT it KNOWS what elements have Angular statements which saves cpu time.

I am building an app which has quite some code, the boot time went from 9 to 4 seconds. :slight_smile:

by the way, when is a component / page etc not declared in both declarations and entryComponents for me the difference between there two are not clear yet :slight_smile:

Thanks for that! Did only BootTime improve, or also other Timings, e.g. Nav.push, Nav.setRoot, slideIns, transitions, and so forth?. I think customers don’t care about BootUp Time too much.

For us is boottime top priority. We are creating a social network app, if it takes too long to launch people abandon the app. I haven’t had any time to test more deeply since building the app takes over 10 minutes per change which undoable for development.

Doesn’t seem to work when the component being pushed to is part of a module, imported into the app.module.ts, unless I’m doing something wrong.

See app.module.ts:

import { NgModule } from '@angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { MyApp } from './app.component';
import { BlogPage } from '../pages/blog/blog';
import { ContactPage } from '../pages/contact/contact';
import { HomePage } from '../pages/home/home';
import { TabsPage } from '../pages/tabs/tabs';
import { AuthModule } from '../auth/authModule';
import { firebaseConfig, firebaseAuthConfig } from './firebaseProject';
import { AngularFireModule } from 'angularfire2';

@NgModule({
  declarations: [
    MyApp,
    BlogPage,
    ContactPage,
    HomePage,
    TabsPage
  ],
  imports: [
    AuthModule,
    IonicModule.forRoot(MyApp),
    AngularFireModule.initializeApp(firebaseConfig, firebaseAuthConfig)
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    BlogPage,
    ContactPage,
    HomePage,
    TabsPage
  ],
  providers: []
})
export class AppModule {}

Then this is the AuthModule:

import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { IonicModule } from 'ionic-angular';

import { LoginComponent } from './login/login';
import { RegisterComponent } from './register/register';
import { ResetpassComponent } from './reset/reset';

@NgModule({
  imports:      [ 
    FormsModule,
    CommonModule,
    IonicModule
   ],
  declarations: [ 
    RegisterComponent,
    LoginComponent,
    ResetpassComponent
  ],
  exports: [
    RegisterComponent,
    LoginComponent,
    ResetpassComponent
  ]
})
export class AuthModule { }

And now, I want to do this in my home.ts:

import { Component } from '@angular/core';

import { NavController } from 'ionic-angular';

import { RegisterComponent } from '../../auth/register/register';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController) {

  }

  goRegister() {
    this.navCtrl.push(RegisterComponent);
  }
}

When I call the goRegister() function, I get this error:

What changed with importing modules? What am I doing wrong?

@seanmavley I had the same issue like you by introducing modules (Module Architecture) in the App. But I managed to resolve that by adding also entryComponents in my custom module.
In your case and in the Auth module, add also the following:

entryComponents: [ RegisterComponent ]

Hope that helps!
George

1 Like

I’m experiencing the same thing as @seanmavley. I’m trying to create an Ionic app using module architecture. @gtsopour suggestion on putting the RegisterComponent in entryComponents solves the problem, but defeats the purpose of having module architecture. To fix the problem, I have to declare RegisterComponent in the Auth module as well as AppModule.

So, I’m assuming Ionic2 does not fully support Angular2 module architecture? I’m very hesitant to have to declare components in multiple places. Smells like spaghetti.

Is there another way to use Angular2 module architecture without re-declaring components in AppModule?

2 Likes

Hello tschreck,
I have already prepared a big Ionic 2 application with module architecture (>15 modules). This is for example my module and the only think I am doing is to import the FeedsModule in the AppModule. That should work for you too. In my opinion, the entryComponents should be removed from the child FeedsModule somehow.

Hope that helps!

import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { CommonModule } from '@angular/common';
import { SharedModule } from '../../app/shared/shared.module';
import { FeedCategoriesComponent } from './feed-categories/feed-categories.component';
import { FeedCategoryComponent } from './feed-category/feed-category.component';
import { FeedsComponent } from './feeds/feeds.component';
import { FeedComponent } from './feed/feed.component';

@NgModule({
  declarations: [
    FeedCategoriesComponent,
    FeedCategoryComponent,
    FeedsComponent,
    FeedComponent
  ],
  imports: [
  	CommonModule,
  	SharedModule
  ],
  exports: [
    FeedCategoriesComponent,
    FeedCategoryComponent,
    FeedsComponent,
    FeedComponent
  ],
  entryComponents:[
    FeedCategoriesComponent,
    FeedCategoryComponent,
    FeedsComponent,
    FeedComponent
  ],
  schemas: [
  	CUSTOM_ELEMENTS_SCHEMA
  ]
})
export class FeedsModule {}

@gtsopour, thanks for the reply. I see what you are doing. You are defining entryComponents in the individual modules and not in the AppModule. This makes sense to me. Here’s what I’m doing:


AppModule.ts:

... OTHER IMPORTS ...
// APP ROOT
import { MyApp } 	from './app.component';

// APPLICATION MODULES - THESE MODULES ARE LOADED WHEN APP LOADS
import { HomeModule } 	from './pages/home/home.module';
import { Page1Module } 	from './pages/page1/page1.module';
import { SharedModule }   	from './shared/shared.module';

@NgModule({
	imports: 
	[
		HomeModule,
		IonicModule.forRoot(MyApp),
		Page1Module,
		SharedModule.forRoot()
	],
	declarations:    [ MyApp ],
	bootstrap:   [ IonicApp ],
	entryComponents:  [ MyApp ]
})
export class AppModule { }

HomeModule.ts

... OTHER IMPORTS ...
import { HomeBaseComponent }		from './base/home-base.component';
import { HomeDesktopComponent }	from './desktop/home-desktop.component';
import { HomeMobileComponent }		from './mobile/home-mobile.component';
import { HomeComponent }			from './home.component';

@NgModule({
	imports: [ IonicModule, NavigationModule ,
	declarations:
	[
		HomeBaseComponent,
		HomeDesktopComponent,
		HomeMobileComponent,
		HomeComponent
	],
	exports: [ HomeComponent ],
	providers: [ ],
	entryComponents: [ HomeComponent ] 
})
export class HomeModule{}

I implemented this and it seems to work. I do not have to surface individual components to the AppModule. Each functional module itself exposes entryComponents. I simply register functional module in AppModule.

Thanks for your feedback.

1 Like

Hi, I got similar exception, but my main.js is minified

0     214474   error    EXCEPTION: No component factory found for t
1     214477   error    ORIGINAL STACKTRACE:
2     214484   error    Error: No component factory found for t at e.Error (native)
at e [as constructor] (http://192.158.0.8:8100/build/main.js:5:5464)

How to avoid to minify main.js? What command you use?
I am using ionic run android -l -c -s --debug
Thanks