2

I'm working with angular, jspm, and es6. I'm working with a base class to inject dependencies onto the constructor and automatically register themselves on 'this'.

This is actually a pattern that exists in React when you extend the base component class. I found this guy's little shortcut method here: http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes

I am looking for a way to do this with Angular, using es6 Classes to bind the injected dependencies to the constructor's "this".

class baseClass {
    constructor(...injections) {
        this._bind(injections)
    }

    _bind(injections) {
        injections.forEach( (injection) => { 
            this[injection.name] = injection;
        });
    }   
}

class DiClass extends baseClass {
    constructor($q, SomeAngularFactory) {
        super($q, SomeAngularFactory);
    }
}

This obviously doesn't work (injection.name is not a thing, i know)... but it almost does. My question is how do i get the "name" of the injected function or object. In this example, the _bind function just gives you the raw object or function... i don't know how to get "$q" or "SomeAngularFactory" as a string.

You can kind of get that by using "Object.getOwnPropertyNames(...injections)", but not inside the _bind function.

Thanks for any feedback or ideas you have.

  • You could parse the the variable names from the string representation of the function. *Should* you do that? Probably not. – Felix Kling May 14 '15 at 00:26

3 Answers3

3

You could do something like this:

class baseClass {
  constructor(injections) {
    Object.assign(this, injections);
  }
}

class DiClass extends baseClass {
  constructor($q, SomeAngularFactory) {
    super({ $q, SomeAngularFactory });
  }
}

Obs.: Like classes, Object.assign is an ES2015 feature and it merges the second (parameter) object into the first one.

dadalt
  • 31
  • 3
0

In AngularJS this injectable arguments works only on development mode. If you go to production and minify your scripts, all injectables should be saved into special property. You can learn more about it in the angular docs. Here how it works with angular controllers

function MyController($q, SomeAngularFactory) {
}
MyController.$inject = ['$q', 'SomeAngularFactory']

Angular 2.0 will be powered by TypeScript and will use annotations to describe injectable variables. For now in anguar 1.3 you still can add static property $inject

class DiClass extends baseClass {
   constructor($q, SomeAngularFactory) {
     super($q, SomeAngularFactory);
   }
}
DiClass.$inject = ['$q', 'SomeAngularFactory'];
just-boris
  • 9,468
  • 5
  • 48
  • 84
0

Angular has a built in method, $injector.annotate(fn), which it uses for dependency injection, and which allows you to get arguments of the function you pass to it. You could utilize it to get the names of all constructor() parameters, and then use $injector.get() to retrieve them (which should be fine performance-wise, since they are cached).

Here's a link to answer in another thread, and a direct link to a fiddle with a demo.

Community
  • 1
  • 1
Maciej Gurban
  • 5,615
  • 4
  • 40
  • 55