Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 5: Using Service from inside Custom Decorator Function

I'm creating a @Log() Decorator Function for debugging purposes;

I want that Decorator to delegate some of it's logic to a LoggingService that in turn depends on other services from the app...

I've been trying a lot of different things, the simplest/most straightforward way was to cache the Main (or Shared) Module's Injector as a static prop on the module itself (see StackBlitz example linked below), and that works for lazy-loaded modules, but not for eagerly loaded ones...

Non-working poc: https://stackblitz.com/edit/angular-j1bpvx?file=app%2Fdecorator.ts

Is there a way I could mkae use of that Service in there??

Thanks!

like image 317
Olivier Clément Avatar asked Jan 03 '23 20:01

Olivier Clément


1 Answers

Class decorator is executed once on class definition. In order to avoid race condition when calling AppModule.injector.get(LoggingService) it should be moved to the place where AppModule.injector is already defined, i.e. class method.

It should be:

constructor.prototype[hook] = function (args) {
  const loggingService = AppModule.injector.get(LoggingService);

  loggingService.log({ ... })
  ...

This also creates tight coupling with AppModule and prevents the units from being reused or tested separately from it. It's recommended to use another object to hold injector property, e.g. assign injector not in main but in child module that is imported into AppModule:

export class InjectorContainerModule { 
  static injector: Injector;

  constructor(injector: Injector) {
    InjectorContainerModule.injector = injector;
  }
}
like image 73
Estus Flask Avatar answered Jan 05 '23 15:01

Estus Flask