What are the differences between $injector.instantiate
, $injector.get
and $injector.invoke
in AngularJS?
Overview. $injector is used to retrieve object instances as defined by provider, instantiate types, invoke methods, and load modules. The following always holds true: var $injector = angular.
It relieves a component from locating the dependency and makes dependencies configurable. It also helps in making components reusable, maintainable and testable. AngularJS provides a supreme Dependency Injection mechanism. It provides following core components which can be injected into each other as dependencies.
Angular Creates the Module Injector tree when the Application starts. At the top of the Module Injector tree, Angular creates an instance of Null Injector . The Null Injector always throws an error unless we decorate the dependency with the Optional decorator.
Given the following service:
app.service('myService', function ($q, $http) {
return {
q: $q,
http: $http
};
});
$injector.get(name, [caller]);
Returns an instance of the requested service.
$injector.get('myService');
// { q: $q, http: $http }
$injector.invoke(fn, [self], [locals]);
Invokes the supplied method and passes along the given arguments from the $injector.
$injector.invoke(function (myService, $http) {
console.log(myService); // { q: $q, http: $http };
console.log(this); // { v: 'im this!' };
console.log($http); // null
}, { v: 'im this!' }, { $http: null });
$injector.instantiate(Type, [locals]);
Creates a new instance of the given Type. Takes a constructor function, then invokes the new instance with the arguments specified in the constructor annotation.
Assume the following 'class':
function Person (fName, lName, $http, $q) {
return {
first_name: fName,
last_name: lName,
http: $http,
q: $q
}
}
Now, if we wanted to create a new Person in our controller, we could do it like this:
app.controller('...', function ($injector) {
var $http = $injector.get('$http');
var $q = $injector.get('$q');
var p = new Person('kasper', 'lewau', $http, $q);
console.log(p); // { first_name: 'kasper', last_name: 'lewau', http: $http, q: $q };
});
Imagine Person
had ~20 or so dependencies, and we were fetching each and every one of them with the $injector.get
method.
Cumbersome! And - you would need to keep your parameters & arguments in sync. ugh.
Instead, you can do this:
app.controller('...', function ($injector) {
var p = $injector.instantiate(Person, {
fName: 'kasper',
lName: 'lewau'
});
console.log(p); // { first_name: 'kasper', last_name: 'lewau', http: $http, q: $q };
});
And - if we wanted to, we could supply locals to the .instantiate
call, so as to override what the internal $injector.get()
would normally get when instantiating.
var p = $injector.instantiate(Person, {
fName: 'kasper',
lName: 'lewau'
}, { $http: 'Nothing!', $q: 'Nothing!' });
console.log(p); // { first_name: 'kasper', last_name: 'lewau', http: 'Nothing!', q: 'Nothing!' };
I hope that explains the difference between the three. If you need more information regarding their differences I would recommend these articles:
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