robisim74/angular-library-starter

StaticInjectorError(Platform: core)[HttpHandler -> Injector]

Closed this issue · 8 comments

Hello everyone,
I'm having a strange error with dependencies and I'm out of ideas. I tried everything in my mind and expend almost two days debugging and nothing.

Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[HttpHandler -> Injector]: 
  StaticInjectorError(Platform: core)[HttpHandler -> Injector]: 
    NullInjectorError: No provider for Injector!
Error: StaticInjectorError(AppModule)[HttpHandler -> Injector]: 
  StaticInjectorError(Platform: core)[HttpHandler -> Injector]: 
    NullInjectorError: No provider for Injector!
    at _NullInjector.get (core.js:1002)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveNgModuleDep (core.js:10854)
    at NgModuleRef_.get (core.js:12087)
    at resolveNgModuleDep (core.js:10854)
    at _NullInjector.get (core.js:1002)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveToken (core.js:1300)
    at tryResolveToken (core.js:1242)
    at StaticInjector.get (core.js:1110)
    at resolveNgModuleDep (core.js:10854)
    at NgModuleRef_.get (core.js:12087)
    at resolveNgModuleDep (core.js:10854)
    at resolvePromise (zone.js:824)
    at resolvePromise (zone.js:781)
    at eval (zone.js:883)
    at ZoneDelegate.invokeTask (zone.js:421)
    at Object.onInvokeTask (core.js:4740)
    at ZoneDelegate.invokeTask (zone.js:420)
    at Zone.runTask (zone.js:188)
    at drainMicroTaskQueue (zone.js:595)
    at ZoneTask.invokeTask [as invoke] (zone.js:500)
    at invokeTask (zone.js:1570)

Let me explain my problem:

I created a library with this starter repo and I have the LocationModule

import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { AddressService } from './address.service';
import { LocationService } from './location.service';

@NgModule({
  imports: [
    HttpClientModule,
  ],
  providers: [
    AddressService,
    LocationService
  ],
  exports: [
    HttpClientModule,
  ]
})
export class LocationModule {}

and here is my LocationService

import { Injectable, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';

import { State } from './state';
import { ResponseModel } from '../model/response.model';
import { API_URL } from '../constants';

@Injectable()
export class LocationService {

  constructor(
    @Inject(API_URL) private apiUrl: any,
    private http: HttpClient
  ) { }

  getStates(): Observable<State[]> {
    return this.http.get<ResponseModel>(this.apiUrl + '/Cadastro/UF')
      .map((res: ResponseModel) => {
        return res.Content;
      });
  }
}

My package.json

{
    "name": "my-lib",
    "private": true,
    "version": "0.0.1",
    "description": "Build an Angular library compatible with AoT compilation and Tree shaking like an official package",
    "main": "./dist/bundles/my-lib.umd.js",
    "module": "./dist/esm5/my-lib.js",
    "es2015": "./dist/esm2015/my-lib.js",
    "scripts": {
        "build": "node tools/build.js",
        "test": "karma start",
        "test:watch": "karma start karma.conf.js --single-run false",
        "pack:lib": "npm run build && npm pack ./dist",
        "publish:lib": "npm run build && npm publish ./dist",
        "publish:lib:next": "npm run build && npm publish --tag next ./dist",
        "compodoc": "compodoc -p tsconfig.json",
        "compodoc:serve": "compodoc -s",
        "watch": "node tools/watch.js"
    },
    "typings": "./dist/my-lib.d.ts",
    "author": "",
    "repository": {
        "type": "git",
        "url": "https://github.com/robisim74/angular-library-starter.git"
    },
    "bugs": {
        "url": "https://github.com/robisim74/angular-library-starter/issues"
    },
    "homepage": "https://github.com/robisim74/angular-library-starter",
    "keywords": [
        "angular",
        "javascript",
        "typescript"
    ],
    "license": "MIT",
    "peerDependencies": {
        "@angular/common": "5.2.9",
        "@angular/core": "5.2.9",
        "moment": "^2.22.0",
        "rxjs": "5.5.7",
        "zone.js": "0.8.21"
    },
    "dependencies": {
        "tslib": "1.9.0"
    },
    "devDependencies": {
        "@angular/animations": "5.2.9",
        "@angular/cli": "^1.7.4",
        "@angular/common": "5.2.9",
        "@angular/compiler": "5.2.9",
        "@angular/compiler-cli": "5.2.9",
        "@angular/core": "5.2.9",
        "@angular/forms": "5.2.9",
        "@angular/platform-browser": "5.2.9",
        "@angular/platform-browser-dynamic": "5.2.9",
        "@angular/platform-server": "5.2.9",
        "@compodoc/compodoc": "^1.1.2",
        "@types/jasmine": "2.6.2",
        "@types/node": "^8.0.47",
        "chalk": "2.3.0",
        "codelyzer": "4.2.1",
        "core-js": "2.5.4",
        "istanbul-instrumenter-loader": "3.0.0",
        "jasmine-core": "^3.1.0",
        "karma": "~2.0.0",
        "karma-chrome-launcher": "2.2.0",
        "karma-coverage-istanbul-reporter": "^1.2.1",
        "karma-jasmine": "~1.1.0",
        "karma-jasmine-html-reporter": "^1.0.0",
        "karma-sourcemap-loader": "0.3.7",
        "karma-spec-reporter": "0.0.31",
        "karma-webpack": "2.0.5",
        "node-watch": "^0.5.8",
        "reflect-metadata": "0.1.12",
        "rollup": "0.50.0",
        "rollup-plugin-license": "0.6.0",
        "rollup-plugin-node-resolve": "3.0.0",
        "rollup-plugin-replace": "^2.0.0",
        "rollup-plugin-sourcemaps": "0.4.2",
        "rxjs": "5.5.7",
        "shelljs": "0.7.8",
        "source-map-loader": "0.2.3",
        "ts-loader": "3.1.1",
        "tslint": "^5.9.1",
        "tslint-angular": "1.0.0",
        "typescript": "2.6.2",
        "uglify-js": "3.1.6",
        "webpack": "3.8.1",
        "zone.js": "0.8.21"
    }
}

I also configured my rollup.config.js

const globals = {
    '@angular/core': 'ng.core',
    '@angular/common': 'ng.common',
    '@angular/common/http': 'ng.common.http',
    'rxjs/Observable': 'Rx',
    'rxjs/Observer': 'Rx',
    'rxjs/Subject': 'Rx',
    'rxjs/observable/of': 'Rx.Observable',
    'rxjs/operator/concatMap': 'Rx.Observable.prototype',
    'rxjs/operator/filter': 'Rx.Observable.prototype',
    'rxjs/operator/map': 'Rx.Observable.prototype',
    'moment': 'moment/moment'
};

export default {
    external: Object.keys(globals),
    plugins: [resolve(), sourcemaps()],
    onwarn: () => { return },
    output: {
        format: 'umd',
        name: 'ng.myLib',
        globals: globals,
        sourcemap: true,
        exports: 'named',
        amd: { id: 'my-lib' }
    }
}

I have an spec file and my test and build script run without problems. I created a yarn link between my lib and my application

My application module (lazy loaded)

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http';
import { LocationModule } from 'my-lib';

import { environment } from '../../environments/environment';

@NgModule({
  imports: [
    CommonModule,
    HttpClientModule,
    // ...
    LocationModule
  ],
  declarations: [
    // ...
  ],
  exports: [
   // ...
    LocationModule
  ],
  providers: [
    { provide: 'API_URL', useValue: environment.apiEndPoint },
    // ...
  ]
})
export class SignupModule {}

In my component I call

import { Component, OnInit } from '@angular/core';
import { LocationService, State } from 'my-lib';
// ...

@Component({
  selector: 'app-nationality',
  templateUrl: './nationality.component.html',
  styleUrls: ['./nationality.component.scss'],
})
export class NationalityComponent implements OnInit {

  public stateList: State[] = [];

  constructor(
    private locationService: LocationService
  ) {  }

  ngOnInit() {
    this.retrieveStates();
    this.retrieveCountries();
  }

  private retrieveStates(): void {
    this.locationService.getStates().subscribe(stateList => {
      this.stateList = stateList;
    });
  }

// ...
}

@wac2007

This error is related to HttpClient module, and in AppModule. If I well remember, it should be a problem with npm or yarn link. Try to google the error: you'll find a lot of issues.

Then in my opinion you don't need to import and export HttpClientModule in your LocationModule, and you don't need to export LocationModule in your SignupModule.

Hi there,
I have the same error.
Any other suggestions?

hi there , i have same error did any one find the solution ??

I found the solution : you should import the HttpClientModule in service.spec and component.spec how use the service and every component.spec relation with service ..

import { TestBed } from '@angular/core/testing';
import { SiteService } from './site.service';
import { HttpClientModule } from '@angular/common/http';

describe('SiteService', () => {
beforeEach(() => TestBed.configureTestingModule({
imports: [HttpClientModule], // here you should import and also in component.spec
providers: [SiteService]
}));

it('should be created', () => {
const service: SiteService = TestBed.get(SiteService);
expect(service).toBeTruthy();
});

});

hi, @wac2007 did you find the solution ??

Hi, did anyone find the solution? I am also facing this issue, when I am trying to use ngx-translate in npm library and importing the same in ionic project

Why this is closed? There is still no solution for that problem. Took me hours for finding out what the error is related to. I use nx from nrwl to build a library. When the lib is in my /libs folder as mentioned everything works. The same lib elsewhere e.g. by using git submodules which includes npm link causes this error. Same code different folders. How is that possible?

Has anybody a suggestion for even a hacky solution?