0

I have written a code where I wanted a Service which returns promise. Now this service I injected in two controllers, these controllers are not scope inherited in view, but than too once I update a model value in controller 1, that updated value gets reflected on controller 2. How come ?

Please follow the code below,

<!DOCTYPE html>
<html lang="en" ng-app="MyApp">
<head>
    <title>Recipe 02 example 01</title>
    <script type="text/javascript" src="D:\Rahul Shivsharan\JavaScript-Framework\AngularJS\angular.js"></script>
    <script type="text/javascript" src="D:\Rahul Shivsharan\JavaScript-Framework\jQuery\jquery-1.11.1.js"></script>
    <script type="text/javascript" src="D:\Rahul Shivsharan\JavaScript-Framework\BootstrapCSS\bootstrap-3.2.0-dist\js\bootstrap.js"></script>
    <link rel="stylesheet" href="D:\Rahul Shivsharan\JavaScript-Framework\BootstrapCSS\bootstrap-3.2.0-dist\css\bootstrap.css"></link>
    <link rel="stylesheet" href="D:\Rahul Shivsharan\JavaScript-Framework\BootstrapCSS\bootstrap-3.2.0-dist\css\bootstrap-theme.css"></link>
    <script type="text/javaScript">
        angular.module("MyApp",[]);
        (function(){
            angular.module("MyApp").controller("myCtrlOne",myCtrlOne)
                                   .controller("myCtrlTwo",myCtrlTwo);

            function myCtrlOne(storedValue){
                var obj = this;                 
                obj.myVal = undefined;

                storedValue.get().then(function(value){
                    obj.myVal = value;
                });

            };

            function myCtrlTwo(storedValue){
                var obj = this;
                obj.myVal = undefined;

                storedValue.get().then(function(value){
                    obj.myVal = value;
                });
            };


        })();

        (function(){
            angular.module("MyApp").factory("storedValue",storedValue);

            function storedValue($q){
                var obj = { get : fn },
                    promise = undefined;

                return obj;

                function fn(){
                    return promise || getData();

                    function getData(){
                        promise = $q.when({
                            label : 'Hello',
                            value : 1000
                        });

                        return promise;
                    };
                };
            }
        })();
    </script>
</head>
<body>
    <div ng-controller="myCtrlOne as one">
        <h2>One</h2>
        <label for="">Stored Value:</label>{{one.myVal | json}} <br/>
        Value: <input  type='text' ng-model='one.myVal.value' />
    </div>



    <div ng-controller="myCtrlTwo as two">
        <h2>Two</h2>
        <label for="">Stored Value:</label>{{two.myVal | json}} <br/>
    </div>
</body>     

Please refer the jsfiddle link below

My Angular-Promise

I am confused.

Please guide me

Rahul Shivsharan
  • 2,481
  • 7
  • 40
  • 59
  • thats what services are for.. for sharing same data among controller – binariedMe Aug 06 '15 at 06:12
  • same service is inside both controller and there is no input to service which means service is input independent so it is obvious that both will return the same data. – Shubham Nigam Aug 06 '15 at 06:16

1 Answers1

3

The answer is that you're you are caching the factory's result.

You can see usage of cache in line:

 return promise || getData();

The factory will run every time it is injected, but will return the cached promise.

Since this is an object, both controllers will point to the same object.

added a print to your fiddle. open the console to see that "getting data" is printed only once.

http://jsfiddle.net/3hb0acdk/

function getData(){
    console.log('getting data');
    promise = $q.when({
    label : 'Hello',
    value : 1000
});

Here is a fiddle that will generate 2 different objects and thus one won't affect the other

http://jsfiddle.net/d0queaat/

function fn(){
    return getData();

    function getData(){
        console.log('getting data');
        var promise = $q.when({
            label : 'Hello',
            value : 1000
        });

        return promise;
    };
};
guy mograbi
  • 27,391
  • 16
  • 83
  • 122
  • But I have not added any setter method in the object returned by service, so how come the value gets updated in service ? – Rahul Shivsharan Aug 06 '15 at 06:17
  • @RahulShivsharan - that's how pointers work.. there is only one object - everyone are looking at the same one. there's no "service object" and "controller object".. it is the same object. – guy mograbi Aug 06 '15 at 06:17
  • @RahulShivsharan if you want to generate multiple objects, I think you should use providers. not sure about it. see: http://stackoverflow.com/questions/15666048/service-vs-provider-vs-factory – guy mograbi Aug 06 '15 at 06:19
  • You can generate multiple objects with a factory too. Besides, JS is pass by value. – skubski Aug 06 '15 at 06:20
  • @skubski - objects are passed by reference. references are passed by value: http://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference – guy mograbi Aug 06 '15 at 06:22
  • Yeah, I kinda double checked after I posted, I stand corrected. Nevertheless you can create new objects with a factory too. – skubski Aug 06 '15 at 06:24
  • @RahulShivsharan - skubski is right, my first answer is incorrect. the reason you're getting the same result is because you write: `return promise || getData();` .. I will edit it.. just a second. – guy mograbi Aug 06 '15 at 06:24
  • @skubski - yes you are right. I was mistaken as well. I corrected my answer. thanks! – guy mograbi Aug 06 '15 at 06:27