#Injecting services into plain classes

1 messages · Page 1 of 1 (latest)

urban aspen
#

Is it supported to inject services into plain classes? (i.e. not Components, Services, Routes, Controllers, etc.). I thought it was, but I'm encountering this error:

Uncaught (in promise) Error: Assertion Failed: Attempting to lookup an injected property on an object without a container, ensure that the object was instantiated via a container.
    at assert (assert.js:43:13)
    at Tool.getInjection (cache-fCezwMOy.js:1881:99)
    at eval (cache-fCezwMOy.js:1160:23)
    at untrack (index.js:468:12)
    at ComputedProperty.get (cache-fCezwMOy.js:1159:75)
    at Tool.getter [as intl] (cache-fCezwMOy.js:312:23)
    at get name (toolbar.js:54:17)

The error makes me think that Tool (the plain class with an injected service) is being instantiated before the container is ready. Here's my setup, where I instantiate the plain class in a property on the service:

// my-app/services/toolbar.js

class Tool {
  @service intl;
  
  constructor(id) {
    this.id = id;
  }
  
  get name() {
    return this.intl.t(TRANSLATION_KEYS[this.id]);
  }
}

// ...

export default class Toolbar extends Service {
  @service intl  

  tools = [
    new Tool('some-id'),
    new Tool('another-id'),
  ];
}

I took a wild guess and tried moving the instantiation of Tools inside the service's constructor, but that didn't seem to change anything:

export default class Toolbar extends Service {
  tools = [];

  constructor() {
    super(...arguments);
    this.tools = [
      new Tool('some-id'),
      new Tool('another-id'),
    ];
  }
}
agile wigeon
#

The object has to have an owner set

#

which you can do manually

median plaza
#

I really want this type of linkage ergo to be first class

urban aspen
#

Ahhh I see. Like this?

class Tool {
  constructor(owner) {
    setOwner(this, owner);
  }
}

export default class Toolbar extends Service {
  tools = [
    new Tool(getOwner(this));
  ]
}