Am just new here. Am developing an android application with ionic and angularjs ontop Cordova. Am having difficulty handling user details stored in localStorage on login in various views. I have Controller1 attached to view1 that the user is directed to on login and the user username displays ok. When I navigate from view1 to view2 attached to Controller2 it also displays user's email. Then if the current user logs out and another user logs in, view1 displays the corrrect new user's username but when I navigate to view2 i see the former user's email until i refresh the page before I get the new user's email displayed correctly. Please how do I handle scope models update?
In my Controller js file I have:
.controller('Controller1', [
'$scope',
'$timeout',
'userAccountService',
function($scope, $timeout, userAccountService,){
$scope.user = {};
if (window.localStorage['USER_DETAILS']){
$scope.isAuthenticated = true;
var getUserDetails = JSON.parse(localStorage.getItem("USER_DETAILS"));
$scope.user.username = getUserDetails.username;
}
$scope.$on('USER_LOGGED_IN', function() {
$scope.isAuthenticated = true;
var getUserDetails = JSON.parse(localStorage.getItem("USER_DETAILS"));
$scope.user.username = getUserDetails.username;
});
});
.controller('Controller2', [
'$scope',
'userDetailsService',
function($scope, userDetailsService){
$scope.user = {};
$scope.user.email = userDetailsService.userDetails.email;
$scope.$on('USER_LOGGED_IN', function() {
$scope.user.email = userDetailsService.userDetails.email;
});
});
In View1 I have:
<ion-list>
<ion-item class="content-margin-bottom content-radius" href="#/me/signin" ng-show="!isAuthenticated">
User Account<span class="float-right link-color">Sign in <i class="icon ion-chevron-right icon-accessory"></i></span>
</ion-item>
<ion-item class="content-margin-bottom content-radius" href="#/me/view2" ng-show="isAuthenticated">
User Account<span class="float-right link-color">{{user.username}}<i class="icon ion-chevron-right icon-accessory"></i></span>
</ion-item>
</ion-list>
This is what I have in my service js file:
.service('userAccountService', function($rootScope, $timeout){
this.logOut = function(){
window.localStorage.removeItem("USER_DETAILS");
};
})
.factory('userDetailsService', function(){
var userDetails = JSON.parse(localStorage.getItem("USER_DETAILS"));
return{
userDetails: userDetails
};
});
in view2 I have:
<ion-list>
<ion-item class="content-radius-top" href="#">
Email<span class="float-right link-color">{{user.email}}</span>
</ion-item>
</ion-list>
I hope this information helps. Again what am trying to achieve here to to be able to get user details as it is in the localStorage and when user logs out and another user logs in, the new user should be able to get his own details displayed. My problem is that I keep on seeing details from the previous user unless i refresh the page. I think I need a way to reset the model values
Views in ionic framework are cached, that's the reason why you keep on seeing the same details.
The dirty trick to solve the problem is to tell your view not to be cached using the attribute cache-view
:
<ion-view view-title="my view" cache-view="false">
Doing this your view will be loaded (controller) all the time. It can be good but you loose some of the performance tricks the frameworks can offer you.
Another option is to clean the cache after the login using the $ionicHistory service.
$ionicHistory.clearHistory()
$ionicHistory.clearCache()
I can see you're broadcasting some events. You could do something there.
UPDATE:
I am not convinced about the implementation of your service. I would do something like this:
(function () {
'use strict';
angular
.module('app.services', [])
.factory('userAccountService', userAccountService);
userAccountService.$inject = ['$q'];
function userAccountService($q) {
var service = {
user: { username: '' },
logIn: logIn,
logOut: logOut,
};
return (service);
function logIn(username, password)
{
this.user = {username: 'Doublechyke'}
}
function logOut()
{
this.user = { username: '' };
}
};
})();
Of course, this is over simplified, but it should do. You would have one service (singleton) which exports 2 methods (logIn and logOut) and one object (user).
You could call the service's methods to login/logout and persist the user logged-in in the object, which would live in the context:
userAccountService.logIn('username', 'password');
in the second view you could read your user straight from the service:
.controller('view2Controller', function($scope, userAccountService) {
$scope.user = userAccountService.user || null;
});
You can see a sample of this simple implementation here.
I would also suggest you to use the angular localstorage.
NOTE:
There are some guidelines which I've used to define my objects. You should try and follow this specs.