Search code examples
angularangular-moduleangular-di

Lazy loading messes up DI on angular


I have a module A that is a npm package that I need to use on module B that is also an npm package that is used on an app.

Module B is lazy loaded by the app.

So I have the following service on module A:

@Injectable({
    providedIn: 'root',
})
export class SomeHandlerService {
    private readonly handlers: HandlerService[] = [];
    constructor() {
        console.log('SomeHandlerService instanciated');
    }

    addHandler(handler: HandlerService): void{
        console.log(`handler count ${this.handlers.length}`);
        console.log(`some? ${this.handlers.some(h => typeof(h) === typeof(handler))}`);
        if(!this.handlers.some(h => typeof(h) === typeof(handler))){
            this.handlers.push(handler);
        }
    }

    runeHandlerLogic (someParam: paramType): Observable<boolean>{
        console.log(`handler count ${this.handlers.length}`);
        const containsHandlers = this.handlers.length > 0;
        if(!containsHandlers){
            return of(false);
        }

        

        return some logic that run handlers
    }

}

Then I register a handler in SomeHandlerService in my other module:

@NgModule({
    imports: [
        myModule
    ],
    other module DI
})
export class ModuleB{
    constructor(
        private myCustomHandler: CustomHandler,
        private someHandlerService: SomeHandlerService,
    ){
        console.log('add handler');
        console.log('handler service');
        console.log(someHandlerService);
        someHandlerService.addHandler(myCustomHandler);
    }
}

Then when my service in the app use the someHandlerService.runeHandlerLogic function the handler count from the console log is always 0. But when I get console log from the add method it is at 1. So there are clearly 2 instances there that are called seperately.

Not sure how to resolve that. Any tips will be appreciated.

Edit There is how the SomeHanlderService is used.

@Injectable({
    providedIn: 'root',
})
export class SomeInterceptor implements HttpInterceptor {

    constructor(
       private someHandlerService: SomeHandlerService
    ) { }

    intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
        

        return this.someHandlerService.runHandlerLogic(someParam: paramType).pipe(doSomeLogic);
    }
}

Solution

  • Turns out that this should always work:

    @Injectable({
        providedIn: 'root',
    })
    

    In my case it wasn't working because I installed my custom npm package directly from the dist folder

    npm install C:\mylocalpackagesource\dist
    

    But I had to install it from the tgz file

    npm install C:\mylocalpackagesource\dist\mypackage.tgz
    

    However I still don't know why installing it directly from the dist folder mess angular dependency injection.