AngularJS Factory vs Service

by Jeff Steinmetz

HTML

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<div class="realm" style="background:yellow">
The service is a Singleton. <br>
If You change the value in A, the change will take effect in B too.<br>
Opposed to this the factory uses $injector.instantiate, so A and B <br>
have different instances. What You change in A will only be changed <br>
in A and vicecersa in B.
</div>

<div class="realm" style="background:#33CC99" ng-controller="ControllerA">

<p>{{testValA}}</p>

<table>
<tr>
<td><button ng-click="getValFromService()"> get value from service </button></td>
<td><button ng-click="getValFromFactory()"> get value from factory </button></td>
</tr>

<tr>
<td><button ng-click="setValInService()"> set value in service </button></td>
<td><button ng-click="setValInFactory()"> set value in factory </button></td>
</tr>
</table>

<p>newValA: <input type="text" ng-model="newValA"></p>

</div>


<div class="realm" style="background:#CC99FF" ng-controller="ControllerB">

<p>{{testValB}}</p>

<table>
<tr>
<td><button ng-click="getValFromService()"> get value from service </button></td>
<td><button ng-click="getValFromFactory()"> get value from factory </button></td>
</tr>

<tr>
<td><button ng-click="setValInService()"> set value in service </button></td>
<td><button ng-click="setValInFactory()"> set value in factory </button></td>
</tr>
</table>

<p>newValB: <input type="text" ng-model="newValB"></p>

</div>

CSS

div.realm {margin:20px;width:600px;border:1px solid black;}

JavaScript

var App = angular.module('App', []);

function FactoryObject() {this.val = "Bar";} // 'value' is a keyword in JavaScript, so using 'val'
FactoryObject.prototype.getVal = function () {return this.val;};
FactoryObject.prototype.setVal = function (arg) {this.val=arg;};
App.factory('MyFactory', function ($injector) {
    return function() { return $injector.instantiate(FactoryObject); };
});

/* Whether you change the following line to 
    App.service('MyService', function() {
        or
    App.factory('MyService', function() {    
    
    They both work, why?
    
    It seems more about how you reference the service with "new"
      var myInstance = new MyFactory();
    Which is different than just calling it directly
      MyService.getVal()
    
*/
App.factory('MyService', function() {
    var _val = "Foo";  
    return {
        getVal: function() { 
            return _val;
        }, 
        setVal : function(arg) { 
            _val = arg; }   
    };       
});

/* 
   you can also define the service using the "this" keyword
   why does this also work?
   why does the above approach also work without the "this" keyword?
   Here is the commented out version of a service that also works:
*/

/*
App.service('MyService', function() {
  this.val = "Foo";
  this.getVal = function() {return this.val;};
  this.setVal = function(arg) {this.val=arg;};
});
*/

function ControllerA($scope,$window,MyService,MyFactory) {

  $scope.testValA = "This is the realm of ControllerA.";
  $scope.newValA = "";
  $scope.myFactoryInstanceA = new MyFactory();
  $scope.text1 = $scope.myFactoryInstanceA.getVal();

  $scope.getValFromService  = function() {$window.alert("A: "+MyService.getVal());}
  $scope.setValInService    = function() {MyService.setVal($scope.newValA);}

  $scope.getValFromFactory  = function() {$window.alert("A: "+$scope.myFactoryInstanceA.getVal());}
  $scope.setValInFactory    = function()...