Reputation: 13206
Okay, so I have a UserFactory
whose return value has a user
property, like so:
angular.module('app')
.factory('UserFactory', function () {
return {
user: user
};
function user () {
return {
age: 'test',
loggedIn: false
}
};
I am injecting this in several places in my app, and I wanted to be able to change the loggedIn
property in everywhere, at least in each controller where it injected.
I have two questions:
How do I changed the loggedIn
property from the controller into which it is injected? I.e.:
angular.module('app')
.controller('HeaderCtrl', function ($scope, $element, $attrs, UserFactory) {
$scope.loggedIn = UserFactory.user().loggedIn;
$scope.change = function () {
//This doesn't work
UserFactory.user().loggedIn = !UserFactory.user().loggedIn;
};
$scope.anotherChange = function () {
//This doesn't work
$scope.loggedIn = !$scope.loggedIn;
};
});
And 2.
How would I keep the user
information updated and linked to my database. In other words, if someone logs in from a different computer and changes the age
property(which would update in my DB), how can I sync that with the other computer?
Thanks
Upvotes: 0
Views: 96
Reputation: 1843
The Best way to keep the factory updated is without using $scope. Here is more advanced solution to share the data between controllers using shared service but without using $scope.
html
<div ng-app="myApp">
<div ng-controller="Controller1 as ctrl">
</br>
<table>
<tr>
<td><B> Enter Age in Controller1</B></td>
<td><input type="text" ng-model="ctrl.userAge"></select></td>
<td><button ng-click="ctrl.userLoggedIn=true"/>Submit</td>
</tr>
</table>
</div>
<div ng-controller="Controller2 as ctrl">
<table>
<tr>
<td><B> Age in controller2 : </B></td>
<td>{{ctrl.userAge}}</td>
</tr>
<tr>
<td><B> LoggedIn in controller2 : </B></td>
<td>{{ctrl.userLoggedIn}}</td>
</tr>
</table>
</div>
</div>
js
(function(app) {
function SharedService() {
this.user = {};
}
angular.extend(SharedService.prototype, {
getUser: function() {
return this.user;
},
setUser: function(user) {
this.user = user;
}
});
function Controller1(SharedService) {
this.sharedService = SharedService;
}
Object.defineProperty(Controller1.prototype,
'userAge', {
enumerable: true, //indicate that it supports enumerations
configurable: false, //disable delete operation
get: function() {
return this.sharedService.getUser().age;
},
set: function(val) {
this.sharedService.getUser().age=val;
}
});
Object.defineProperty(Controller1.prototype,
'userLoggedIn', {
enumerable: true, //indicate that it supports enumerations
configurable: false, //disable delete operation
get: function() {
return this.sharedService.getUser().loggedIn;
},
set: function(val) {
this.sharedService.getUser().loggedIn=val;
}
});
function Controller2(SharedService) {
this.sharedService = SharedService;
}
Object.defineProperty(Controller2.prototype,
'userAge', {
enumerable: true, //indicate that it supports enumerations
configurable: false, //disable delete operation
get: function() {
return this.sharedService.getUser().age;
},
set: function(val) {
this.sharedService.getUser().age=val;
}
});
Object.defineProperty(Controller2.prototype,
'userLoggedIn', {
enumerable: true, //indicate that it supports enumerations
configurable: false, //disable delete operation
get: function() {
return this.sharedService.getUser().loggedIn;
},
set: function(val) {
this.sharedService.getUser().loggedIn=val;
}
});
app.service('SharedService', SharedService);
app.controller('Controller1', Controller1);
app.controller('Controller2', Controller2);
})(angular.module('myApp', []));
Upvotes: 0
Reputation: 1218
To answer your questions
1. You should setup your factory to something like this...
angular.module('app')
.factory('UserFactory', function () {
var user = {};
user.loggedIn = false;
user.login = function() {
// Logic to login your user
user.loggedIn = true;
}
// Now return the whole user object
return user;
// Remember anything after a return is not executed
});
Now in your controllers you can access the loggedin variable by
UserFactory.loggedIn // will be true or false
2. This one gets a little tougher, theres a couple different ways you could do it.
Probably the easiest way would be to use sockets. Since you are trying to update something across all clients that are connected from a single change in your database, you will need some way to force an interaction from the server to the client without the client asking for it.
Thats what sockets do. You can set it up to 'listen' for events from the server and react when those events are fired.
Or, you could poll the server every certain amount of time, or on route changes to check for new data.
Upvotes: 0
Reputation: 11228
For the first question, you need to check and understand your code properly.
In your factory function, you pass an object (eventually) that is not stored anywhere. Each time you call the service, it passes a new object. Thus, first create an object and then pass it. That way, subsequent calls will always return the same object.
app.factory('UserFactory', function() {
var userObject = {
age: 25
loggedIn: false
};
return {
get: function () {
return userObject;
},
set: function (user) {
userObject = user;
}
};
});
As shown above, when you call your factory's get()
function, you will get the user details. When you call the set()
function and pass the latest details, you can overwrite the user object.
For your second question, the best way to carry it out is to call a function that makes use of the service above. Call this function each time the route changes. That is, if the user moves to a new page / route, call the function which will get the latest details from the back end and which will then call the above service's set()
function to store the latest user details.
Upvotes: 1