valor-software / ngx-bootstrap

Fast and reliable Bootstrap widgets in Angular (supports Ivy engine)
https://valor-software.com/ngx-bootstrap
MIT License
5.53k stars 1.69k forks source link

Error: No provider for ComponentLoaderFactory! #1348

Closed TsengSR closed 7 years ago

TsengSR commented 7 years ago

FIX: use .forRoot() docs preview available here: http://valorkin.github.io/ng2-bootstrap/#/

I am receiving this exception after upgrading to the latest 1.16-x version (from 1.13)

EXCEPTION: Uncaught (in promise): Error: No provider for ComponentLoaderFactory!
BaseError@https://localhost:44320/lib/@angular/core/bundles/core.umd.js:1225:31 [angular]
AbstractProviderError@https://localhost:44320/lib/@angular/core/bundles/core.umd.js:1400:13 [angular]
NoProviderError@https://localhost:44320/lib/@angular/core/bundles/core.umd.js:1439:13 [angular]
ReflectiveInjector_.prototype._throwOrNull@https://localhost:44320/lib/@angular/core/bundles/core.umd.js:3370:23 [angular]
ReflectiveInjector_.prototype._getByKeyDefault@https://localhost:44320/lib/@angular/core/bundles/core.umd.js:3407:24 [angular]
ReflectiveInjector_.prototype._getByKey@https://localhost:44320/lib/@angular/core/bundles/core.umd.js:3357:24 [angular]
ReflectiveInjector_.prototype.get@https://localhost:44320/lib/@angular/core/bundles/core.umd.js:3119:20 [angular]
NgModuleInjector.prototype.get@https://localhost:44320/lib/@angular/core/bundles/core.umd.js:8914:44 [angular]
AppView.prototype.injectorGet@https:[…]

I have an angular2 application with lazy loaded modules. Trying to add ComponentLoaderFactory to the NgModule provider list, but its not working neither.

My Module definition:

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

import { CoreModule } from '../core/core.module';
import { ModalModule, TypeaheadModule } from 'ng2-bootstrap/ng2-bootstrap';
import { ComponentLoaderFactory } from 'ng2-bootstrap/component-loader';

import { TagsComponent } from './components/tags.component';
import { TagService } from './services/tags.service';

import { TagsRoutingModule } from './tags-routing.module';

@NgModule({
    imports: [
        TagsRoutingModule,
        FormsModule,
        HttpModule,
        CommonModule,

        ModalModule,
        TypeaheadModule,

        CoreModule
    ],
    declarations: [
        TagsComponent
    ],
    providers: [
        ComponentLoaderFactory,
        TagService
    ]
})
export class TagsModule { }

And the app routing module:

const routes: Routes = [
    { path: 'settings', component: EmptyComponent },
    {
        path: '', component: DashboardComponent, children: [
            { path: '', component: DashboardComponent },
            { path: 'home', component: HomeComponent },
            { path: 'welcome', component: WelcomeComponent },
            { path: 'tags', loadChildren: 'app/modules/tags/tags.module#TagsModule' },
            { path: '**', component: NotFoundComponent }
        ]
    },
    { path: '**', component: NotFoundComponent }
];

@NgModule({
    imports: [
        RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })
    ],
    exports: [RouterModule]
})
export class AppRoutingModule { }
guzmo commented 7 years ago

I had a problem that was similar and I had to add .forRoot() when importing the module. Might be a hint in this case too.

Cheers

TsengSR commented 7 years ago

Nope, that results in Error: RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead. which is correct as forRoot should only be called inside the application module

shilpaprabhun commented 7 years ago

I am facing the same issue :(

marval2 commented 7 years ago

Solved for me: imports: [ ... ModalModule.forRoot(), ... ],

guzmo commented 7 years ago

Thought it would help :P

olaf89 commented 7 years ago

is .forChild() option exposed?? I cannot use it.

valorkin commented 7 years ago

You don't need it (forChild()) Check demo/src here to see how it works

TsengSR commented 7 years ago

This forRoot/forChild semantics just seem wrong in my eyes.

What will happen if we have two modules which both need ng2-bootstrap?

By angular2 "semantics" (for routing module), forRoot should only be called in the app module and not in the lazy loaded ones.

Do we now have to expect, that putting the ng2-bootstrap in another lazy loaded module breaks the application again? Or will then be forced to include ng2-bootstrap in the main application, even if we don't know if any module would ever use it?

No matter how you turn it around, it looks wrong and we shouldn't have to call .forRoot for anything except the angular2 routing module., which is a core component of the whole angular2 application

valorkin commented 7 years ago

I had same filling initially, but I need to split providers from components, and as for now it is recommended way

rayer4u commented 7 years ago

I'm not fixed yet.The new version of ng2-bootstrap with anguar2 2.0.0, 2.4.0 all have this problem when I use ModalDirective in template.

valorkin commented 7 years ago

Are you using .forRoot()?

gilbertogwa commented 7 years ago

I fixed this problem using TooltipModule.forRoot() instead of TooltipModule (module from ng2-bootstrap)

defra91 commented 7 years ago

@marval2 solution worked for me. Need to add forRoot() in module import

CoderPoet commented 6 years ago

you can import BsRootModule

batcoder1 commented 6 years ago

ModalModule.forRoot() only runs if the modal is in root component "/", but it's in child fails. I need open modal in a child component. Any solution?

valorkin commented 6 years ago

Import modal module in child module without for root

batcoder1 commented 6 years ago

I try it, but doesnt work. When try to load the modal, change to url root. My modal is in '/catalogo', but if I put the modal in route '/' works perfectly.

valorkin commented 6 years ago

Stackblitz to reproduce

batcoder1 commented 6 years ago

I found the problem, my button was and in href it had '#', for this, in route / the modal run, but in other route not.

ghost commented 3 years ago

The solution is in root module we need to add with forRout and in child module we need to add only the required module with out forRout. Patent componet BsDatepickerModule.forRoot(), Child component BsDatepickerModule