Skip to content
Thomas David Kehoe edited this page Jun 26, 2017 · 23 revisions

Services are typically said to be a good idea because they modularize your code. But there's a more important reason to use services. $scope shares data between controllers and templates. It doesn't share data between controllers. To share data between controllers you use a service. If you're having issues with child scopes and parent scopes, maybe you should be using a service.

Angular has five types of services:

  • Value returns a value.
  • Factory is the most often used service. They make lots of the same thing, i.e., every time you call the service you get another copy, all the same.
  • Service use the new keyword and create a singleton service, i.e., a unique instance of the service.
  • Providers do something with .config.
  • Constant

Value

app.value("message", "Hello world!");

You inject the value as a dependency thus, and then call it:

app.controller("myController", ["$scope", "message", function ($scope, message) {
console.log(message);
}];

Listing the dependency twice is done in case you intend to minimize your code. If you don't intend to minimize your code, save time and complexity:

app.controller("myController", "function ($scope, message) {
console.log(message); // Hello, world!
};

You also need to link the file in index.html:

<script type="text/javascript" src="javascript/services/messageValue.js"></script>

Factory

Factories are like values except that they inject a function instead of a value.

The factory syntax is:

app.factory('myFactory', function() {
...
});

If you need to inject dependencies:

app.factory('myFactory', function(dependency, anotherDependency) {
...
});

And remember to link the factory from index.html.

No $scope in factories

You can't inject $scope into services. Think about it, the purpose of a service is to pass data between controllers, and each controller has its own $scope. Services have to be outside of all the scopes. Instead you use return to pass data out of a service.

Inject the dependency into your controller and link the factory in index.html:

<script type="text/javascript" src="javascript/services/myFactory.js"></script>

You can pass data into a factory through dependencies.

All factories must return something. This is how data is passed out of a factory, to a controller:

app.factory('myFactory', function(dependency, anotherDependency) {
var something = null;
return something;
});

Call your factory

Angular factories use "lazy instantiation." That means that a factory executes when it's injected as a dependency, not when it's called. What's lazy about this I don't know, maybe the Angular developers were too lazy to make factories execute when you want them to. To make a factory execute when it's called you must create an object called return within the factory:

app.factory("myFactory", function() {
  console.log("Factory injected!");

  return {
    executeMyFactory: function() {
      console.log("Factory executed!");
    }
  }

});

In the controller you then call the object:

console.log("This is just before the factory is called.")
authorizedUserFactory.queryGetRecord(); // call factory
console.log("This is just after the factory is called.")

You should then see:

This is just before the factory is called.
Factory called!
This is just after the factory is called.

Service

A service can pass data between controllers.

Provider

Constant

Clone this wiki locally