Angular1 Factories

angular1

// Angular 1 - Factories:

Angular Factories can be used for many different things. Some of the most common 
use-cases are server-side communication via HTTP and abstracting Models to 
persist application state and changes across controllers. Angular Factories are 
a great way to create reusable features and code blocks throughout our 
application.

You may have heard of factories as a design pattern in many programming 
languages, but Angular's factories are different to those in practice (maybe 
not in spirit :). You can create a factory using the angular.factory() method 
like so:

app.factory('ExampleFactory', function ExampleFactory($rootScope, $http, $location) {
   return function myReusableFunction() {
      // do something fancy
   };
});

It's often good practice to create an exports Object inside your Factories and 
return it. This helps with explicit internal naming which helps you see which 
methods / variables are private or not. In this app, we'll need to get our 
messages, so let's create a function to do that. Angular uses the $http service 
to communicate with the server, so we'll inject it:

app.factory('InboxFactory', function InboxFactory ($http) {
   var exports = {};

   exports.getMessages = function () {
      return $http.get('json/emails.json')
         .error(function (data) {
            console.log('There was an error!', data);
      });
   };

   return exports;
});

Promises are very important inside Angular, they allow you to organize functions 
that take a long time to do things (e.g. HTTP requests). Promises in Angular are 
implemented with $q:

var deferred = $q.defer();
deferred.promise.then(
  function whenThingsGoSunny(){},
  function whenThingsDontGoSoSunny(){}
);

When making HTTP requests in Angular you'll often use the $http service which is 
based on $q. As we just saw, $q allows you to use .then() to include a success 
and an error function. When using $http, you can do something very similar (but 
without the .then():

$http({method: 'GET', url: '/someUrl'})
   .success(function(data, status, headers, config) {
      // this callback will be called asynchronously
      // when the response is available
   })
   .error(function(data, status, headers, config) {
      // called asynchronously if an error occurs
      // or server returns response with an error status.
   });

app.controller('InboxCtrl', function($scope, InboxFactory) {
   InboxFactory.getMessages()
      .success(function(jsonData, statusCode) {
         console.log('The request was successful!', statusCode, jsonData);
         // Now add the Email messages to the controller's scope
         $scope.emails = jsonData;
   });
});

See how the InboxFactory factory is available as an injectable in our 
controller? That's dependency injection helping us out again! We then call the 
getMessages method on the factory and using the $http()'s success method (
$http() was returned from getMessages()), we can then add the list of emails / 
messages to our controller's $scope and use it in the view. i.e. The 
success(fn) is available from chaining when we do http() or http.get(), etc…
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License