1

I have developed an application with Angular 12, and now I want to develop a library which will provide services to this application as well as other applications to come.

I can build the library, build and run the application, and when the service in the library has just a method which logs to console, it works fine.

However, the final goal of this library is to make HTTP calls on a REST API.

As soon as I want to use the HttpClient in the service with a test URL, I can still build the library and the application, but when I run the application, I get the following error:

core.js:6479 ERROR Error: inject() must be called from an injection context
    at injectInjectorOnly (core.js:4745)
    at Module.ɵɵinject (core.js:4755)
    at Object.EshopDaoService_Factory [as factory] (eshop-dao.service.ts:8)
    at R3Injector.hydrate (core.js:11438)
    at R3Injector.get (core.js:11257)
    at R3Injector.get (core.js:11268)
    at Object.get (core.js:25036)
    at lookupTokenUsingModuleInjector (core.js:3342)
    at getOrCreateInjectable (core.js:3454)
    at Module.ɵɵdirectiveInject (core.js:14737)

Here is the code of the service, where the test method which logs to console and which works fine is commented

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
    providedIn: 'root'
})
export class EshopDaoService {

    private readonly apiRoot = 'https://api.tvmaze.com';

    constructor(
        private http: HttpClient
        ) { }

    /*
    getShow(id: number): Observable<any> {
        const url = `${this.apiRoot}/shows/${id}`;
        return this.http.get(url);
    }
    */

    getShow(id: number): void {
        console.log('id: ' + id);
    }

}

Here is the tsconfig.app.json:

{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "module": "esnext",
        "outDir": "./out-tsc/app",
        "experimentalDecorators": true,
        "allowJs": true,
        "types": []
    },
    "angularCompilerOptions": {
        "enableIvy": true,
        "allowEmptyCodegenFiles": true
    },
    "files": [
        "src/main.ts",
        "src/polyfills.ts"
    ],
    "include": [
        "src/**/*.d.ts"
    ]
}

Eric Malalel
  • 185
  • 1
  • 17
  • You need to register the `HttpClientModule` module from '@angular/common/http' with your library so the injector is known. – Igor Oct 01 '21 at 14:35
  • Can you please add the `tsconfig.app.json` file of the project to your question? – thisdotutkarsh Oct 01 '21 at 14:43
  • Maybe you can find some hints here: https://stackoverflow.com/questions/51485868/inject-must-be-called-from-an-injection-context – MikeOne Oct 01 '21 at 14:43
  • added tsconfig.app.json to the question. – Eric Malalel Oct 01 '21 at 15:09
  • @EricMalalel Try adding `"paths": { "@angular/*": [ "../node_modules/@angular/*" ] }` to the `compilerOptions` in `tsconfig.json`. – thisdotutkarsh Oct 01 '21 at 15:17
  • There was a configuration problem in my Angular Workspace. I fixed it thanks to [this post](https://stackoverflow.com/questions/65709951/getting-inject-must-be-called-from-an-injection-context-after-upgrading-to-a) and now it works fine. – Eric Malalel Oct 01 '21 at 17:09

1 Answers1

0

I think you should declare the service as provider in your library and then in the project import HttpClientModule.

@Injectable()
export class EshopDaoService {
// .... your code
}

In the module of your library

@NgModule({
declarations: [
    YourComponentLibrary,
    ...
],
imports: [CommonModule],
exports: [YourComponentLibrary],
providers: [EshopDaoService]
})
export class YourModuleLibrary { } 

and then in your AppModule

 @NgModule({
   declarations: [
        AppComponent
      ],
   imports: [
        BrowserModule,
        HttpClientModule,
        YourLibraryModule
      ],
   providers: [],
   bootstrap: [AppComponent]
 })
 export class AppModule { }