Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject ngx bootstrap modules into child module - Angular 4

My application folder structure is like below:

>app
  app.module.ts
  app.routing.ts
>>auth
  login.component
  auth.module.ts
  atuh.routing.module.ts

Now I would like to use the ngx-intl-input module which has dependency on ngx-bootstrap. I would like to include intl-input in the login component.

So if I import ngx-bootsrap in auth.module...

auth.module.ts

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginComponent } from './login/login.component';
import { AuthRoutingModule } from './auth-routing.module';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { NgxIntlTelInputModule } from 'ngx-intl-tel-input';
@NgModule({
  imports: [
    CommonModule,
    AuthRoutingModule,
    BsDropdownModule.forRoot(),
    NgxIntlTelInputModule
  ],
  declarations: [LoginComponent]
})
export class AuthModule { }

I get the following error:

ERROR Error: Uncaught (in promise): Error: 
StaticInjectorError[ComponentLoaderFactory]: 
  StaticInjectorError[ComponentLoaderFactory]: 
    NullInjectorError: No provider for ComponentLoaderFactory!
Error: StaticInjectorError[ComponentLoaderFactory]: 
  StaticInjectorError[ComponentLoaderFactory]: 
    NullInjectorError: No provider for ComponentLoaderFactory!
    at _NullInjector.get (core.js:993)
    at resolveToken (core.js:1281)
    at tryResolveToken (core.js:1223)
    at StaticInjector.get (core.js:1094)
    at resolveToken (core.js:1281)
    at tryResolveToken (core.js:1223)
    at StaticInjector.get (core.js:1094)
    at resolveNgModuleDep (core.js:10878)
    at NgModuleRef_.get (core.js:12110)
    at resolveDep (core.js:12608)
    at _NullInjector.get (core.js:993)
    at resolveToken (core.js:1281)
    at tryResolveToken (core.js:1223)
    at StaticInjector.get (core.js:1094)
    at resolveToken (core.js:1281)
    at tryResolveToken (core.js:1223)
    at StaticInjector.get (core.js:1094)
    at resolveNgModuleDep (core.js:10878)
    at NgModuleRef_.get (core.js:12110)
    at resolveDep (core.js:12608)
    at resolvePromise (zone.js:824)
    at resolvePromise (zone.js:795)
    at eval (zone.js:873)
    at ZoneDelegate.invokeTask (zone.js:425)
    at Object.onInvokeTask (core.js:4744)
    at ZoneDelegate.invokeTask (zone.js:424)
    at Zone.runTask (zone.js:192)
    at drainMicroTaskQueue (zone.js:602)
    at <anonymous>

I tried to include them in the app.module.ts, and even then I am also getting the same error. Any idea how to solve it? I can share more details if needed.

like image 279
Sri Kanth Avatar asked Dec 18 '17 19:12

Sri Kanth


3 Answers

I was getting the following error in my Angular application based on CoreUI:

NullInjectorError: StaticInjectorError(AppModule)[BsDropdownToggleDirective -> BsDropdownDirective]

It turned out my issue was that I had a directive misplaced in my template.

I had dropdownToggle in a button with no parent dropdown directive.

Fixed by switching my button from this:

<button class="btn btn-primary" type="button" dropdownToggle>
  Search
</button>

. . . to this:

<button class="btn btn-primary" type="button">
  Search
</button>
like image 198
Tom Benyon Avatar answered Sep 18 '22 22:09

Tom Benyon


None of the solutions here worked for me.

The error I was getting: NullInjectorError: No provider for BsDropdownDirective!

I tried this by chance and it fixed it for me. Add this to providers in app.module.ts:

... providers: [BsDropdownConfig], bootstrap: [AppComponent] ...

like image 29
Aykut Ucar Avatar answered Sep 20 '22 22:09

Aykut Ucar


Use BsDropdownModule.forRoot when importing into AppModule. Use just BsDropdownModule when importing anywhere else.

Why?

The static forRoot() is intended to be registered with the root injector. This is to ensure that its providers are shared application-wide.

As you can see from the source code, the forRoot method returns a module with providers.

https://github.com/valor-software/ngx-bootstrap/blob/development/src/dropdown/bs-dropdown.module.ts

If you import just the 'BsDropdownModule', it has no providers. Anywhere else that you want to import the module (like AuthModule), you should import just BsDropdownModule:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoginComponent } from './login/login.component';
import { AuthRoutingModule } from './auth-routing.module';
import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { NgxIntlTelInputModule } from 'ngx-intl-tel-input';
@NgModule({
  imports: [
    CommonModule,
    AuthRoutingModule,
    BsDropdownModule,
    NgxIntlTelInputModule
  ],
  declarations: [LoginComponent]
})
export class AuthModule { }
like image 31
pixelbits Avatar answered Sep 21 '22 22:09

pixelbits