I have this class-defined component (transpiled later by webpack and babel back into ES5). I need to use the $http service in one of its methods. How do I do that? Where do I inject $http as a dependency? If I do it in the constructor arguments, I get an error as if I hadn't injected it at all. Maybe classes is not the way to go here?
angular.module('myApp').component('home', {
template: require('./home.component.html'),
controller: class HomeCtrl {
constructor() {
}
doMe() {
$http.get('http://www.yahoo.com/');
}
}
});
A component is injectable by default @Component() (or @Directive() ) includes @Injectable() . Don't expect to get a specific instance of a component injected. This works for example with constructor(@Host() private parentComponent) where DI lookup is limited to parent injectors up to the injector of the host element.
Which Component can be Injected as a Dependency In AngularJS? In Angular. JS, dependencies are injected by using an “injectable factory method” or “constructor function”. These components can be injected with “service” and “value” components as dependencies.
The @Injectable() decorator defines a class as a service in Angular and allows Angular to inject it into a component as a dependency. Likewise, the @Injectable() decorator indicates that a component, class, pipe, or NgModule has a dependency on a service. The injector is the main mechanism.
ES2015 classes (or transpiled classes) are just syntactic sugar over prototypal inheritance. What this means is that the methods you define are put on the prototype of the "class". In order to be able to access the dependencies injected in the constructor, you need to somehow store them for later reference by the prototype method.
This is usually done by putting them on the instance:
function HomeController($http) {
this.$http = $http;
}
HomeController.prototype.doMe = function() {
this.$http.get('http://www.yahoo.com/');
};
In class-based syntax this translates to:
class HomeController {
constructor($http) {
this.$http = $http;
}
doMe() {
this.$http.get('http://www.yahoo.com/');
}
}
EDIT:
If you are using TypeScript, you can save some boilerplate by using access modifiers on the constructor arguments. E.g.:
class HomeController {
constructor(private $http) {}
}
...which is shorthand for:
class HomeController {
private $http;
contructor($http) {
this.$http = $http;
}
}
EDIT 2:
If you want to make your controller minification-friendly, you can use one of the options described here (possibly along with a tool like ngAnnotate). For example, this is how you could use the "$inject
Property Annotation" method:
ES5
HomeController.$inject = ['$http'];
function HomeController($http) {...}
HomeController.prototype.doMe = function() {...}
ES2015
class HomeController {
constructor($http) {...}
doMe() {...}
}
HomeController.$inject = ['$http'];
// OR
class HomeController {
static get $inject() { return ['$http']; }
constructor($http) {...}
doMe() {...}
}
TypeScript
class HomeController {
static $inject = ['$http'];
constructor(private $http) {}
doMe() {...}
}
The class should have explicit $inject
annotation in order to be properly minified:
class HomeCtrl {
static get $inject() {
return ['$http'];
}
// or unstandardized shortcut:
// static $inject = ['$http'];
constructor($http) {
this.$http = $http;
}
doMe() {
this.$http...
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With