How To Set Value Of One Service From One Controller, And Update Value Of Another Controller With This Service
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">×</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"