How to access module in child class using Aurelia DI?

42 Views Asked by At

With Aurelia V1, I'm trying to call abstract init() from the Parent, where init() is implemented in the Child. init() uses a module, that was injected in the Child. I guess I'm seeing an error because the dependency injection initialization is not completed when Parent calls Child.init(), but how do I work around that?

I've tried several ways, including Aurelia resolvers like lazy and parent.

export abstract class Parent {
  protected constructor() {
    this.init();
  }

  protected abstract init();
}
@autoinject()
export class Child extends Parent {
  constructor(
    private i18n: I18N, // how to import this?
  ) {
    super();
  }

  protected init() {
    this.i18n.tr() // throws error
  }
}

Message: Cannot read properties of undefined (reading 'tr')

Possible solutions

1. Use a different structure so that Aurelia lifecycle methods get called

In this case, I don't really wan't to do that, because these are just plain utility classes (validators).

2. Call init from Child class instead of Parent

export abstract class Parent {
  protected constructor() {}

  protected abstract init();
}
@autoinject()
export class Child extends Parent {
  constructor(
    private i18n: I18N,
  ) {
    super();
    this.init();
  }

  protected init() {
    this.i18n.tr() // works 
  }
}

Of course I could just call init from Child, which would work. Still, I try to understand if there's a better solution or if there's an "the Aurelian way".

3. Add i18n to Parent constructor and pass it with super()

export abstract class Parent {
  protected constructor(protected i18n: I18N) {}

  protected abstract init();
}
@autoinject()
export class Child extends Parent {
  constructor(
   i18n: I18N,
  ) {
    super(i18n);
  }

  protected init() {
    this.i18n.tr() // works 
  }
}

Again, this would work, but I don't want to change all existing child classes. Any other ideas?

1

There are 1 best solutions below

1
W.Kurek On

Use Container.instance.get() approach in child method.

import {Container} from 'aurelia-framework'

@autoinject()
export class Child extends Parent {
  private i18n: I18N;


  protected init() {
     this.i18n = Container.instance.get(I18N);

      this.i18n.tr('KEY') 
   }
 }