4

I've been using the approach described in an MSDN blog post to simplify extending components without needing to provide all the dependencies in the super() call. However this has stopped working in Angular 7 with Typescript 3.

So what's happening is that after bootstrapping, I'm trying to store the injector in a service and afterwards I try to retrieve it.

platformBrowserDynamic().bootstrapModule(AppModule).then(ref => {
  // Store module's injector in the AppInjector class
  console.log('Expected #1: storing app injector');
  AppInjector.setInjector(ref.injector);
})

and then in the base component I fetch the stored injector

export class BaseComponent {
  constructor() {
    console.log('Expected #2: retrieving stored injector');
    const injector = AppInjector.getInjector();
  }
}

However looking at the console, the order is reversed – first the BaseComponent's constructor is called whichafter the promise of boostrapModule() is resolved.

I'm not sure if bootstrapping is behaving differently now in Angular 7, as the console logs hint. The very same solution used to work in Angular 6 with Typescript 2, but with version 7 it has stopped working. Here's a stackblitz of the broken app based on the MSDN article: https://stackblitz.com/edit/component-inheritance-angular-7

So the fundamental question is – how to guarantee that AppInjector.setInjector() happens before AppInjector.getInjector()?

Gonçalo Peres
  • 11,752
  • 3
  • 54
  • 83
Lightheaded
  • 644
  • 8
  • 23
  • 1
    Would that bother you to do it in the bootstraped component ? Seems to work : https://stackblitz.com/edit/component-inheritance-angular-7-mzhem6?file=src/app/app.component.ts –  Nov 07 '18 at 08:13
  • Use AppModule constructor https://stackblitz.com/edit/component-inheritance-angular-7-dfd2wr – Muhammed Albarmavi Nov 07 '18 at 08:26
  • Thanks! Both suggestions help circumvent the problem :) – Lightheaded Nov 08 '18 at 12:08

1 Answers1

7

I have set the injector service in AppModule and that mean I will inject Injector and set it in the constractor of AppModule and store the injector service in global object

export class AppModule { 
  constructor(injector:Injector){
  // Store module's injector in the AppInjector class
  console.log('Expected #1: storing app injector');
  AppInjector.setInjector(injector);
  }
}

demo

Muhammed Albarmavi
  • 23,240
  • 8
  • 66
  • 91
  • Thanks, this seems to be working. Althought I went for storing the injector in the `AppComponent` instead of `AppModule` as per trichetriche's comment, I will mark your answer as accepted, as it works too. Feels somewhat hacky to do so, but as long as it works, right? :) – Lightheaded Nov 08 '18 at 11:56
  • 1
    Both are acceptable but if the you extend `AppComponent` with base class `AppModule` will be the place to set injector because `AppModule` is create before `AppComponent`. – Muhammed Albarmavi Nov 09 '18 at 07:54
  • Can you send the full final example to plunkr? – Rasshu Feb 26 '19 at 18:18
  • 2
    @rsb2097 this live example https://stackblitz.com/edit/component-inheritance-angular-7-dfd2wr?file=src%2Fapp%2Fbase.component.ts – Muhammed Albarmavi Feb 27 '19 at 04:49