Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Angular Decorator to reduce repetitive code?

I have a I18nService that needs to be initialized in 90% of my components. The procedure to do this is importing the service, importing the translation file, implementing ngOnInit() and calling the services init() function.

Now I am trying to reduce the repetitive code with the help of Class Decorators. The problem I'm currently facing is using my I18nService inside the decorator since Decorators seem to run at compile time. I was trying to solve the problem with injectors and following this article: https://netbasal.com/inspiration-for-custom-decorators-in-angular-95aeb87f072c but got AppModule undefined.

How can I solve the problem? Are Decorators the right choice to achieve this to begin with?

like image 404
dtrinh Avatar asked Jun 07 '17 15:06

dtrinh


1 Answers

You can store Injector in constructor AppModule and then use it inside patched ngOnInit method to get some Service registered in your app

app.module.ts

@NgModule({
  ...
  providers: [AnalyticsService],
})
export class AppModule {
  constructor(private injector: Injector) {
    AppModule.injector = injector;
  }

  static injector: Injector;
}

page-track.decorator.ts

import { AnalyticsService, AppModule } from './app.module';

export function PageTrack(): ClassDecorator {
  return function ( constructor : any ) {
    const ngOnInit = constructor.prototype.ngOnInit;
    constructor.prototype.ngOnInit = function ( ...args ) {
      let service = AppModule.injector.get(AnalyticsService);
      service.visit();
      ngOnInit && ngOnInit.apply(this, args);
    };
  }
}

app.component.ts

@Component({
  selector: 'my-app',
  templateUrl: `./app.component.html`
})
@PageTrack()
export class AppComponent {}

Plunker Example

like image 155
yurzui Avatar answered Sep 19 '22 21:09

yurzui