I have the following class (only the relevant part):
import { AppInjector } from '@app/shared/utility/app-injector';
import { HttpService } from '@app/shared/services/http.service';
export class Lazy<T> {
private readonly _http: HttpService = AppInjector.get(HttpService);
private _init() {
// Usage of this._http
}
}
So basically, this is a simple type but that needs to use the Angular HttpService
.
To do so, I created a file with the following code:
import { Injector } from '@angular/core';
export let AppInjector: Injector;
export function setAppInjector(injector: Injector) {
if (AppInjector) {
console.error('Programming error: AppInjector was already set');
}
else {
AppInjector = injector;
}
}
And I'm setting it in the constructor of my AppModule
:
export class AppModule {
constructor(injector: Injector) {
setAppInjector(injector);
}
}
Finally, I use it for example in a service:
@Injectable({
providedIn: 'root',
})
export class FooService {
private readonly ROUTE: string = "/api/foo";
private _campaigns: Lazy<ICampaign[]> = new Lazy<ICampaign[]>(`${this.ROUTE}/campaigns`);
public get campaigns(): Lazy<ICampaign[]> {
return this._campaigns;
}
}
And in a component, I can do something like:
export class FooComponent implements OnInit {
constructor(private _fooService: FooService) {}
public async ngOnInit(): Promise<void> {
await this._fooService.campaigns.load();
}
}
This works pretty well but I'm wondering how I could make this more generic.
Indeed, say I wanted to create a separate npm package with just this class, I can't tell users to create the setAppInjector
function and to register it in the AppModule
(and I could not even use it from my npm package anyway...).
So I'm searching for an Angular way to make this generic, something like passing something in the providers
property of the decorator of the AppModule
.
Any idea?