Search code examples
angularjspass-by-referenceangular-servicesangular-controller

Communication Between Two Controllers; References vs Primatives


I have seen an unexpected behaviour in Angularjs with its factories. I used a factory to communication between two controllers.

In the first scenario it is working fine but not in second one. The only difference between them is that in first example I am accessing the name from the view but in second one I am accessing in scope variable.

Scenario 1

<div ng-controller="HelloCtrl">
    <a ng-click="setValue('jhon')">click</a>
</div>
<br />
<div ng-controller="GoodbyeCtrl">
    <p>{{fromFactory.name}}</p>
</div>

//angular.js example for factory vs service
var app = angular.module('myApp', []);

    app.factory('testFactory', function() {
        var obj = {'name':'rio'};
        return {
            get : function() {
                return obj;
            },
            set : function(text) {
               obj.name = text;
            }
        }          
    });

    function HelloCtrl($scope, testFactory) {
        $scope.setValue = function(value) {
            testFactory.set(value);
        }
    }

    function GoodbyeCtrl($scope, testFactory) {
        $scope.fromFactory = testFactory.get();
    }

Scenario 2

<div ng-controller="HelloCtrl">
    <a ng-click="setValue('jhon')">click</a>
</div>
<br />
<div ng-controller="GoodbyeCtrl">
    <p>{{fromFactory}}</p>
</div>

//angular.js example for factory vs service
var app = angular.module('myApp', []);
    app.factory('testFactory', function() {
        var obj = {'name':'rio'};
        return {
            get : function() {
                return obj;
            },
            set : function(text) {
               obj.name = text;
            }  
        }               
    });

    function HelloCtrl($scope, testFactory) {
        $scope.setValue = function(value) {
            testFactory.set(value);
        }
    }
    function GoodbyeCtrl($scope, testFactory) {
        $scope.fromFactory = testFactory.get().name;
    }

Solution

  • The difference is:

    Scenario I

    $scope.fromFactory = testFactory.get(); 
    
    <div ng-controller="GoodbyeCtrl">
    <p>  {{fromFactory.name}}</p>
    </div>
    

    The $scope variable is set to testFactory.get() which is an object reference. On each digest cycle the watcher fetches the value of the property name using the object reference. The DOM gets updated with changes to that property.

    Scenario II

    $scope.fromFactory = testFactory.get().name;
    
    <div ng-controller="GoodbyeCtrl">
        <p>{{fromFactory}}</p>
    </div>
    

    The $scope variable is set to testFactory.get().name which is a primative. On each digest cycle, the primative value doesn't change.

    The important difference is that when a reference value is passed to a function, and a function modifies its contents, that change is seen by the caller and any other functions that have references to the object.