Skip to content Skip to sidebar Skip to footer

How To Set Value Of One Service From One Controller, And Update Value Of Another Controller With This Service

I am new in this field and want to write a app, now I meet some problems. Here is a simple version of my code, what I want is the API only show signUp first. After I press signUp a

Solution 1:

Basically you are setting values in factory object after user clicks on submit but that doesn't reflect in UI as you have not updated the scope object this.logged.So to tell main controller fromsign up controller that change the this.logged $scope value we can use $emit or $broadcast

Apart from $watch approach you can even use $broadcast to achieve this.

Working DEMO

Just add this below code in your JS file controllers

signUpControl

(function(){
    'use strict';
    angular.module('myApp.signUp').controller('signUpControl',signUpControl);
    signUpControl.$inject = ['whichToShow','$rootScope'];
    function signUpControl(whichToShow,$rootScope){
        alert("haha");
        this.logIn=function(){
            whichToShow.setVar(true);
            $rootScope.$broadcast('login');//broadcasting that user has logged in
            //alert("running set!");
        };
    };
})

mainControl

(function(){
    'use strict';
    angular.module('myApp.dashboard').controller('mainControl',mainControl);

    mainControl.$inject = ['whichToShow','$rootScope'];

    function mainControl(whichToShow,$rootScope){
        var mc = this;
        mc.main ={};
        mc.main.logged=whichToShow.getVar();
        alert(mc.main.logged);

       // below code will listen to the broadcast and do the necessary process..
        $rootScope.$on('login',function(event,args){
                mc.main.logged=whichToShow.getVar();
        });
    }
})

Solution 2:

You need watch for the changes on the logged value from the service.

That is all you need to do.

(function() {
  angular.module('myApp', ['myApp.dashboard', 'myApp.value', 'myApp.signUp']);
})();

(function() {
  angular.module('myApp.dashboard', []);
})();

(function() {
  angular.module('myApp.value', []);
})();

(function() {
  angular.module('myApp.signUp', []);
})();

(function() {
  'use strict';
  angular.module('myApp.dashboard').controller('mainControl', mainControl);

  mainControl.$inject = ['$scope', 'whichToShow'];

  function mainControl($scope, whichToShow) {
    $scope.$watch(() => whichToShow.getVar(), (newValue, oldValue) => this.logged = newValue)
  }
})();

(function() {
  'use strict';
  angular.module('myApp.value').factory('whichToShow', function() {

    var logged = false;
    var service = {};

    return {
      getVar: function() {
        return logged;
      },
      setVar: function(value) {
        logged = value;
      }

    }
  });
})();

(function() {
  'use strict';
  angular.module('myApp.signUp').controller('signUpControl', signUpControl);
  signUpControl.$inject = ['whichToShow'];

  function signUpControl(whichToShow) {
    this.logIn = function() {
      whichToShow.setVar(true);
    };
  };
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>


<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<div ng-app="myApp">
  <div ng-controller="mainControl as mc">
    <div>
      <div ng-hide="mc.logged">

        <button type="button" class="btn" data-toggle="modal" data-target=".signUp">Sign Up</button>
      </div>
      <div ng-show="mc.logged">
        <button>Sign Out</button>
      </div>
    </div>


    <div class="signUp modal fade" id="signUp" ng-controller='signUpControl as sc'>
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h4 class="modal-title">sigh up</h4>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">&times;</button>
          </div>
          <div class="modal-body">
            <form id="signUpForm" name="signUpForm" ng-submit="sc.logIn()">
              <label for="email">
                <span>email:</span>
                <input type="email" name="email">
              </label>
              <button class="submit" id="signUpSubmit" type="submit" value="signUp">submit</button>
            </form>


          </div>
          <div class="modal-footer">

          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Working solution on Codepen


Solution 3:

You are still trying to set the value of primitives here, rather than object properties. In JavaScript, primitives are passed byValue, not byReference, so whichToShow.getVar(); is returning true or false rather than returning a reference to logged. Therefore, you won't see changes to logged unless you call .getVar() again, to get the new value. This is why most answers you have seen so far have had some form of $watch, $broadcast, or similar, to alert your mc that it should ask again for the logged variable's current value.

If you want to avoid using a $watch, you should use an object instead of a primitive. by using an object, you can pass the object byReference, which will allow angular to see the changes to the properties wherever there is a reference set.

In your factory, return an object:

(function() {
  'use strict';
  angular.module('myApp.value').factory('whichToShow', function() {
    alert("running2");
    var status = {
      logged: false
    };
    var logged = false;
    return {
      getVar: function() {
        return status;
      },
      setVar: function(value) {
        status.logged = value;
      }

    };
  });
})();

In mainControl, use a reference to this object:

(function() {
  'use strict';
  angular.module('myApp.value').factory('whichToShow', function() {
    alert("running2");
    var status = {
      logged: false
    };
    return {
      getVar: function() {
        return status;
      },
      setVar: function(value) {
        status.logged = value;
      }

    };
  });
})();

And finally, use the object property in the HTML:

<div ng-hide="mc.status.logged">
...
<div ng-show="mc.status.logged">
...

https://plnkr.co/edit/Pindt2LYxDxyk8C5Axp1?p=preview

I might even go one step further and just return the object directly by the service, and skip the getVar and setVar functions.


Solution 4:

You can put some variable globally or in your rootcontroller,lets says isLoggedIn

now with one service you can set this variable on signingIn

and use it like this {

}<span data-ng-if="!isLoggedIn">Sign In</span> <span data-ng-if="isLoggedIn">Sign Out</span>


Post a Comment for "How To Set Value Of One Service From One Controller, And Update Value Of Another Controller With This Service"