Skip to content

Instantly share code, notes, and snippets.

@0x8801
Last active October 10, 2016 11:04
Show Gist options
  • Save 0x8801/b49a2782ad9d01aa90efd42c99b4b14a to your computer and use it in GitHub Desktop.
Save 0x8801/b49a2782ad9d01aa90efd42c99b4b14a to your computer and use it in GitHub Desktop.

Services vs. Factories vs. Providers

Technically speaking, their declarations differ in the following way

var app = angular.module('app', [])

// Service - Constructor function(s) is instantiated at service declaration therefore one shared instance of the function
app.service('myService', function() {
  this.myFunction = function() {
    return {
      "My message"
    }
  } 
});

// Factory - Constructor function(s) is passed around in an object(can be used as a constuctor elsewhere e.g. new myFactory()) but there is still one shared instance of the factory. 
app.factory('myFactory', function() {
  return {
    myMessage: "My message"
  }
});

// Provider - Strictly uses the $get function as it's constructor function
app.provider('myProvider', function() {
  var message = "My message"
  return {
    setAdditionalMessage: function(additionalMessage) { 
      message += " " + additionalMessage
    },
    $get: function() {
      return {
        myMessage: message
      }
    }
  }
});

app.config(function(myProviderProvider) {
  myProviderProvider.setAdditionalMessage("is a dope message"); // Introduces flexiblity since you can modify data before sharing to other modules
});

app.controller('app', function($scope, myService, myFactory, myProvider) {
  // Usage
  $scope.message = [ myService.myFunction, myFactory.myMessage, myProvider.myMessage ]; // Service and Factory return "My message" but Provider returns "My message is a dope message"
});
  • Services are useful when designing simple applications where it's not necessary to be fluent
  • Factories are more powerful than services and allow you to use OOP principles better e.g. 'new' constructor, private functions/variables
  • Providers are more flexible than Factories and Services. They allow you to modify data that is going to be shared to the app through modules before the modules are injected

Route Data

There are 2 approaches to this, activate and resolve.

// activate
var app = angular.module('app');

app.controller('app', function($scope, someService) {
  /**
   * Function call that resolves route data in a promise
   * Can be used with ng-view and a loading visual in the View
   */
  activate();
  
  function activate() {
    return someService.getData().then(function(result){
      $scope.data = result
      return $scope.data
    })
  }
});

// resolve
app.config(function($routeProvider) {
  $routeProvider.when('/someRoute', {
    templateUrl: 'routeView.html',
    controller: 'routeController',
    resolve: { 
      someService: someService
     }
  })
});

app.service('someService', function($http) {
  // A promise that resolves with data from an external api
  this.getData: function() {
    return $http.get('/api/endpoint')
             .then(function(result) {
                return result
              })
             .catch(function(error) {
              console.log(error)
             })
  }
})

app.controller('routeController', function($scope, someService) {
  /**
    * Since the route definition couples this controller to the service in the config, 
    * the route will only transition to when the someService.getData() resolves.
    * If it rejects then the route won't transition to at all
    */
  $scope.data = someService.getData();
  
})

The main difference between activate and resolve is that activate loads the view then binds data to the view after while resolve waits for data before loading the view

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment