In my library I have a service with this code:
import { Inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DataInjectorModule } from '../../data-injector.module';
// @dynamic
@Injectable()
export class RemoteDataService<T> {
@Inject('env') private environment: any = {};
public type: new () => T;
constructor(
model: T,
) {
this.http = DataInjectorModule.InjectorInstance.get(HttpClient);
}
// ...
}
The data-injector.module
(existing reason is only avoid circular dependency):
import { NgModule, Injector } from '@angular/core';
// @dynamic
@NgModule({
declarations: [],
imports: [],
providers: [],
exports: [],
})
export class DataInjectorModule {
static InjectorInstance: Injector;
constructor(injector: Injector) {
DataInjectorModule.InjectorInstance = injector;
}
}
In my library's main module file:
import { ModuleWithProviders } from '@angular/compiler/src/core';
import { NgModule, Injector } from '@angular/core';
import { DataInjectorModule } from './data-injector.module';
import { RemoteDataService } from './services/remote-data/remote-data.service';
// @dynamic
@NgModule({
declarations: [],
imports: [
DataInjectorModule,
],
providers: [],
exports: [],
})
export class DataCoreModule {
static InjectorInstance: Injector;
constructor(injector: Injector) {
DataCoreModule.InjectorInstance = injector;
}
public static forRoot(environment: any): ModuleWithProviders {
return {
ngModule: DataCoreModule,
providers: [
RemoteDataService,
{ provide: 'env', useValue: environment }
]
};
}
}
Finally in my application's app.module.ts
:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { DataCoreModule } from 'data-core';
import { AppRoutingModule } from './app-routing.module';
import { environment } from 'src/environments/environment';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
DdataCoreModule.forRoot(environment),
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Build goes well, but in the browser I get this error:
Error: Can't resolve all parameters for RemoteDataService: (?).
at getUndecoratedInjectableFactory (core.js:11338)
at injectableDefOrInjectorDefFactory (core.js:11328)
at providerToFactory (core.js:11371)
at providerToRecord (core.js:11358)
at R3Injector.processProvider (core.js:11256)
at core.js:11230
at core.js:1146
at Array.forEach (<anonymous>)
at deepForEach (core.js:1146)
at R3Injector.processInjectorType (core.js:11230)
I checked several questions about this topic in StackOverflow, like this but almost everywhere just the @Injectable()
was the missing part, but in this case I use this decorator.
Any idea how can I solve this issue?
I found a solution (actually a workaround). I think this isn't an elegant way, but it's wokring.
I created an
EnvService
class what can pick up theenvironment
parameter from the module, and doesn't have sideeffects with constructor attributes:Then in my library's main module file I set up the
EnvService
instead ofRemoteDataService
:Finally in my
RemoteDataService
changed the@Inject
solution to anInjectorInstance.get(EnvService)
solution:So the
RemoteDataService
'sconstructor
attributes are untouched, but the service can access to the environment variables over theEnvService
.