Angular can't use HttpClient in external library
Asked Answered
U

6

20

When I try to instantiate the HttpClient service in an external library, then consume that library in an Angular application, I'm getting StaticInjectorError errors:

With Angular 5.0.0:

AppComponent_Host.ngfactory.js? [sm]:1 ERROR Error:
  StaticInjectorError[InjectionToken DocumentToken]:   
  StaticInjectorError[InjectionToken DocumentToken]: 
     NullInjectorError: No provider for InjectionToken DocumentToken!
     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 _createClass (core.js:10919)
     at _createProviderInstance$1 (core.js:10889)

With Angular 5.2.0-rc.0:

ERROR Error: StaticInjectorError(AppModule)[HttpXsrfTokenExtractor ->
InjectionToken DocumentToken]:    StaticInjectorError(Platform:
core)[HttpXsrfTokenExtractor -> InjectionToken DocumentToken]: 
    NullInjectorError: No provider for InjectionToken DocumentToken!
    at _NullInjector.get (core.js:994)
    at resolveToken (core.js:1292)
    at tryResolveToken (core.js:1234)
    at StaticInjector.get (core.js:1102)
    at resolveToken (core.js:1292)
    at tryResolveToken (core.js:1234)
    at StaticInjector.get (core.js:1102)
    at resolveNgModuleDep (core.js:10836)
    at _createClass (core.js:10877)
    at _createProviderInstance$1 (core.js:10847)

I reproduced this with a blank @angular/cli application importing a blank library seed from angular-library-starter which just imports and tries to use HttpClient:

(import lines truncated for brevity)

Application: app.module.ts:

@NgModule({
  declarations: [ AppComponent ],
  imports: [ ..., ArithmeticModule.forRoot() ],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

Application: app.component.ts:

@Component({
  ...
})
export class AppComponent {
  constructor(private sum: SumService) {}
}

For the library, all I did was import HttpClientModule in the library module, and then try to inject it in SumService:

Library: arithmetic.module.ts:

@NgModule({
    imports: [ HttpClientModule ]
})
export class ArithmeticModule {
    public static forRoot(): ModuleWithProviders {
        return {
            ngModule: ArithmeticModule,
            providers: [ SumService ]
        };
    }
}

Library: sum.service.ts:

@Injectable()
export class SumService {
  constructor(private http: HttpClient) {}
  ....
}

This setup causes the StaticInjectorError errors mentioned at the top of the post.

  • In the rollup config, I've added @angular/common/http/ng.common.http as external/global.
  • I've tried this with many different setups, library seeds, with rollup, and with webpack. It all results in the same issue.

Any ideas?

Unisexual answered 9/1, 2018 at 18:30 Comment(8)
HttpClient is defined in HttpClientModule.Finish
Have you tried exporting HttpClientModule in the library module, too? What I like to do is make @angular/common a peer dependency, and let the hosting application handle the rest by importing HttpClientModule in the app-module and all that.Deficient
@R.Richards thanks for the suggestion, but it looks like that results in the same error for me. I have @angular/common as a peer dependency, and marked as external in rollup/webpack.Unisexual
Have you tried to provide the SumService in the app.module.ts?Deficient
Yes, that also does not fix the issue. Regardless, SumService is provided in the library, and the library is imported, so I don't believe I'd ever have to directly provide the library service in the app itself.Unisexual
I did just realize that this actually works in AoT, but not in JIT. ng serve fails, but ng serve --aot does not.Unisexual
any update @Unisexual ? did you resolve this issue ?Orsay
Yup. I've hit this problem too. Any resolution?Brookebrooker
A
1

The way your are consuming the sum.service is just a sub module of the main module, which is your app.module.ts. The HttpClientModule will need to be imported into the app.module.ts to be consumed by any sub module.

The reason you don't get an error with AOT is because in that sense there is a different injector.

In the app.module.ts

@NgModule({
  imports: [ HttpClientModule ]
})
Airs answered 30/9, 2019 at 14:51 Comment(0)
E
0

I ran into similar problem and fixed upgrading the NgxMaskModule (2.2.2) and added the NgxMaskModule.forRoot() in the module import.

Effusion answered 23/1, 2018 at 13:24 Comment(3)
I'm sadly not using that module. But I may look at what they changed in their last update. Maybe that gives me some cluesTashia
Check the import order. HttpModule must be imported before HttpClientModule. Like: imports: [ BrowserModule, FormsModule, HttpModule, HttpClientModule ]Pamela
That's the current order of my imports and the problem persists. I've tried different ways of sorting it but it does not really help.Tashia
O
0

Try Importing HttpClient module in your app.module.ts.

HttpClientModule will be your peer dependency in this case,

so you have to import HttpClientModule in your main app.

Orphaorphan answered 25/1, 2018 at 22:42 Comment(0)
R
0

we are using HttpClient for translate module. I'm using importing way that below;

// translate
HttpClientModule,
TranslateModule.forRoot({
       loader: {
            provide: TranslateLoader,
            useFactory: HttpLoaderFactory,
            deps: [HttpClient]
        }
    }),
Refutative answered 25/1, 2018 at 23:25 Comment(0)
F
0

I faced this problem too and I got it fixed in this way:

add HttpClientTestingModule in TestBed configuration object

 beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule]
    });
  });

import it form

import { HttpClientTestingModule } from '@angular/common/http/testing';
Fogel answered 16/5, 2023 at 12:13 Comment(0)
T
-1

StaticInjectorError

Try like import HttpClient Module in module.ts and add the service to the providers might work.

Tumefy answered 17/10, 2018 at 12:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.