Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$injector.instantiate VS $injector.get VS $injector.invoke in angularjs

Tags:

angularjs

What are the differences between $injector.instantiate, $injector.get and $injector.invoke in AngularJS?

like image 696
Shreyansh Bele Avatar asked Jul 12 '15 12:07

Shreyansh Bele


People also ask

What is an injector 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.

Why we use $inject in AngularJS?

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.

What is null injector in Angular?

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.


1 Answers

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:

  • http://taoofcode.net/studying-the-angular-injector/
  • http://taoofcode.net/studying-the-angular-injector-annotate/
  • http://taoofcode.net/studying-the-angular-injector-invoke/
  • http://taoofcode.net/studying-the-angular-injector-getservice/
  • http://taoofcode.net/studying-the-angular-js-injector-instantiate/
like image 179
Kasper Lewau Avatar answered Oct 06 '22 12:10

Kasper Lewau