Force page to refresh after a POST angularjs - javascript

I tried to put a $ state.reload in my controller after a POST request, but it does not refresh my page. Therefore, after I register my form, the data is not updated on my page .. I am obliged to refresh manually so that it shows me the right data.
.controller('editCtrl', function($scope, $stateParams, $state, AppService) {
$scope.infos = AppService.getObject();
console.log($scope.infos);
AppService.user($scope.infos).then(function(response){
$scope.user = response;
console.log($scope.user);
});
$scope.save = function (currObj) {
AppService.edituser($scope.form,$scope.infos).then(function(response){
AppService.addObject(currObj);
console.log(currObj);
$state.reload('menu.infosUser');
$ionicLoading.hide();
$state.go('menu.infosUser',{reload: true});
});
};
})
I will reply as soon as possible to all proposals :)

If you really want to reload your page then use location.reload() for reloading the page like
.controller('editCtrl', function($scope, $stateParams, $state, AppService) {
$scope.infos = AppService.getObject();
console.log($scope.infos);
AppService.user($scope.infos).then(function(response){
$scope.user = response;
console.log($scope.user);
});
$scope.save = function (currObj) {
AppService.edituser($scope.form,$scope.infos).then(function(response){
AppService.addObject(currObj);
console.log(currObj);
location.reload();
});
};
})
Or you can reload your state by using only $state.go('menu.infosUser',{reload: true});, it will clear your cached data, Eg
.controller('editCtrl', function($scope, $stateParams, $state, AppService) {
$scope.infos = AppService.getObject();
console.log($scope.infos);
AppService.user($scope.infos).then(function(response){
$scope.user = response;
console.log($scope.user);
});
$scope.save = function (currObj) {
AppService.edituser($scope.form,$scope.infos).then(function(response){
AppService.addObject(currObj);
console.log(currObj);
$ionicLoading.hide();
$state.go('menu.infosUser',{reload: true});
});
};
})

Related

How to display current data from localStorage?

I'm able to login, logout and display logged in user information from localStorage, however if i logout and login again with different user app displays information of previous user! this should not happen as i can see new user data in localStorage. New data displays correctly if i refresh the page manually!
I need this app to display currently logged in user's data as it's already available in localStorage..
routes.js
angular.module('app.routes', [])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('menu', {
url: '/side-menu',
templateUrl: 'templates/menu.html',
controller: 'menuCtrl'
})
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'loginCtrl'
})
.state('menu.welcome', {
url: '/welcome',
views: {
'side-menu21': {
templateUrl: 'templates/welcome.html',
controller: 'welcomeCtrl'
}
}
})
$urlRouterProvider.otherwise('/user-type')
});
Login:
Here i'm authenticating user through web service, which sends back user object in JSON format which is being stored in localStorage with key 'user' and it works fine.
.controller('loginCtrl', ['$scope', '$stateParams', '$state', '$http',
function ($scope, $stateParams, $state, $http) {
$scope.user = {
username: '',
password: ''
};
$scope.login = function(){
var apiUrl = "...";
return $http.post(apiUrl, $scope.user).then(function(response){
window.localStorage.setItem('user', angular.toJson(response.data));
$state.go('menu.welcome');
});
};
}
])
Logout:
Here i'm logging out user by removing 'user' JSON object from localStorage, and redirecting him back to login state, and it works fine.
.controller('menuCtrl', ['$scope', '$stateParams', '$state',
function ($scope, $stateParams, $state) {
$scope.user = angular.fromJson(window.localStorage.getItem('user'));
$scope.logout = function(){
// here i'm removing user from localStorage
window.localStorage.removeItem('user');
$state.go('login');
};
}
])
Menu:
Here i'm displaying user info which is sent from 'menuCtrl' (it's not updating logged in user's data here even if it's available in localStorage)
<h3 id="menu-heading1" class="left-menu-headings">{{user.first_name}} {{user.last_name}}</h3>
<h4 id="menu-heading2" class="left-menu-headings">{{user.email}}</h4>
I already tried following in logout function with no success:
$window.localStorage.clear();
$ionicHistory.clearCache();
$ionicHistory.clearHistory();
Any idea why it's not displaying current data from localStorage?
Use ion view enter to define your user
$scope.$on( "$ionicView.enter", function( scopes, states ) {
$scope.user = angular.fromJson(localStorage.get("user"));
});
Remove the set from the controller declaration.
This will make the user get loaded each time it enters and not each time the controller gets initialized
I have a wild guess, based on your controller name, that "menuCtl" actually lives through the reloging, so it never gets re-initialized. You should add some console.logs around the
$scope.user = angular.fromJson(window.localStorage.getItem('user'));
To see if it is getting called the 2nd time when you relogin. If not, you may have a number of options to follow, for example, add event listeners to the controllers, and broadcast events on login/logout so that controllers would refresh their scope data.
Use $rootScope:
This problem is mostly due to the menuController being shared by the views and not being reloaded, in such case, you could use $rootScope.user which unlike $scope.user is shared by all your controllers, use as follows:
logout controller
.controller('menuCtrl', ['$scope', '$stateParams', '$state',
function ($scope, $stateParams, $state, $rootScope) { // <-- add $rootScope
// use $rootScope.user instead of $scope.user
$rootScope.user = angular.fromJson(window.localStorage.getItem('user'));
// rest of your code is fine.
$scope.logout = function(){
// here i'm removing user from localStorage
window.localStorage.removeItem('user');
$state.go('login');
};
}
login controller
.controller('loginCtrl', ['$scope', '$stateParams', '$state', '$http',
function ($scope, $stateParams, $state, $http, $rootScope) { // <-- add $rootScope
// $scope.user = { <-- change to $rootScope
$rootScope.user = {
username: '',
password: ''
};
$scope.login = function(){
var apiUrl = "...";
return $http.post(apiUrl, $rootScope.user).then(function(response){
window.localStorage.setItem('user', angular.toJson(response.data));
// update $rootScope.user:
$rootScope.user = angular.fromJson(window.localStorage.getItem('user'));
$state.go('menu.welcome');
});
};
}
])
empty or delete the $scope.user
.controller('menuCtrl', ['$scope', '$stateParams', '$state', '$window',
function ($scope, $stateParams, $state) {
$scope.user = angular.fromJson(window.localStorage.getItem('user'));
$scope.logout = function(){
// here i'm removing user from localStorage
$window.localStorage.removeItem('user');
$state.go('login');
delete $scope.user;
/*or $scope.user = {}*/
};
$scope.login = function(){
var apiUrl = "...";
return $http.post(apiUrl, $rootScope.user).then(function(response){
$window.localStorage.setItem('user', angular.toJson(response.data));
// update $rootScope.user:
$rootScope.user = angular.fromJson($window.localStorage.getItem('user'));
$state.go('menu.welcome');
});
};
}
])

Controller scope variable not loading until refresh

I have a login controller
myApp.controller('LoginCtrl', ['$scope', '$http','$location', function($scope, $http, $location) {
$scope.login = function() {
var data = JSON.stringify({user: $scope.user.id, password: $scope.user.password, type: "m.login.password"});
$http.post("http://localhost:8008/_matrix/client/api/v1/login", data).then(function mySuccess(details){
$http.post('/login',details.data).success(function(response){
console.log(response);
});
$location.path('home');
}, function myError(err) {
console.log(err);
alert("Invalid username/password")
});
};
}]);
and a home controller
myApp.controller('HomeCtrl', ['$scope', '$http','$location', function($scope, $http, $location) {
console.log("Hello World from home controller");
var refresh = function() {
$http.get('/roomNames').success(function(response) {
console.log("I got the data I requested");
$scope.roomNames = response;
});
}
refresh();
}]);
As seen, if the login details are correct, the LoginCtrl changes the route to be home.html.
However, when I run the application and login successfully, the HomeCtrl is supposed to make a get request to the server for data for the logged in user.
What I want is this data to be loaded as a list in the home.html. Here's my home.html
<h3 class="subHeader"> Rooms </h3>
<ul class="nav nav-sidebar">
<!-- <li class="active">Overview <span class="sr-only">(current)</span></li> -->
<li ng-repeat="room in roomNames"><a>{{room}}</a></li>
</ul>
However, on successful login, the roomNames variable is empty initially. As soon as I refresh the page, the html list gets populated.
How do I ensure the list is populated as soon as the home.html page opens?
try using the success and errorcallbacks from $http, it would be better to place this functionality into a factory
myApp.controller('HomeCtrl', ['$scope', '$http', '$location',
function($scope, $http, $location) {
console.log("Hello World from home controller");
var refresh = function() {
$http.get('/roomNames')
.then(function successCallback(response) {
$scope.roomNames = response;
}, function errorCallback(response) {
//output an error if failed?
});
}
refresh();
}
]);
This is because, you move on to home page before your server you access. Therefore, on the home page, you will not get the data, and get them after the refresh.
Do redirected to the page only after successful authentication.
myApp.controller('LoginCtrl', ['$scope', '$http','$location', function($scope, $http, $location) {
$scope.login = function() {
var data = JSON.stringify({user: $scope.user.id, password: $scope.user.password, type: "m.login.password"});
$http.post("http://localhost:8008/_matrix/client/api/v1/login", data).then(function mySuccess(details){
$http.post('/login',details.data).success(function(response){
console.log(response);
$location.path('home'); // Redirect after success login
})
.catch(function(data){
console.error("Error in login",data);
});
}, function myError(err) {
console.log(err);
alert("Invalid username/password")
});
};
}]);

How to make data in Angular service persist through page refresh

I have an Angular service that looks like:
var lunchrServices = angular.module('lunchrServices', []);
lunchrServices.service('authService', function () {
var user = null;
this.login = function (userEmail) {
user = userEmail;
};
this.logout = function () {
user = null;
};
this.currentUser = function(){
return user;
}
});
I use this service on a controller on the main page of my application like so:
var lunchrControllers = angular.module('lunchrControllers', []);
lunchrControllers.controller('MainPageController', ['$scope', '$http', '$state', 'authService',
function ($scope, $http, $state, authService) {
$scope.logIn = function () {
$http.post('/api/users/authenticate', {email: $scope.email, password: $scope.password}).
success(function (data, status, headers, config) {
// lines of interest
authService.login($scope.email);
$state.go('users');
}).
error(function (data, status, headers, config) {
$scope.errorMessages = data;
$scope.password = "";
})
}
}]);
With the users state displaying the following (I'm using ui-router to plug this in a ui-view):
div(class='container')
h1 Welcome {{user}}
// other stuff
The controller for this page looks like:
lunchrControllers.controller('UserController', ['$scope', '$http', '$state', 'authService',
function ($scope, $http, $state, authService) {
$scope.user = authService.currentUser();
//other stuff
}]);
When the user taken to this page through the $state.go('users') call, {{user}} is correctly populated.
The problem, however, is that refreshing the page now results in {{user}} being empty. How can I have the data stored in the service persist through page refreshes?
You can set a cookie or use localStorage. There is a $cookies service in angular.
For a localstorage solution you will have to google around.
shove the user object into a cookie that never expires and then try to read it from there before making your request next time they reload the page.

Pass $scope object to route, keep if refresh

Lets say i list all users in a list, when i click a user i want to route to a new view and get the data for the selected person.
What is the preferred way? Should i move the data i already got when i listed the users or should i create a new server call?
My first thought is to pass the data, but the problem with this is that the data the gets lost if the user refreshes the page.
What is the best practice to solve this?
Small example:
(function() {
var app = angular.module('app');
var controllerId = 'app.controllers.views.userList';
app.controller(controllerId, [
'$scope', 'UserService',function ($scope, userService) {
var vm = this;
vm.users = [];
userService.getAllUsers().success(function (data) {
vm.users= data.users;
});
var gotoUser = function(user) {
// Pass the user to UserDetail view.
}
}
]);
})();
<div data-ng-repeat="user in vm.users" ng-click="vm.gotoUser(user)">
<span>{{customer.firstname}} {{customer.lastname}}</span>
</div>
i now list the user details in UserDetail view, this view is now vulnerable against a browser refresh.
Typically most people just create a new server call, but I'll assume you're worried about performance. In this case you could create a service that provides the data and caches it in local storage.
On controller load, the controller can fetch the data from the service given the route params and then load the content. This will achieve both the effect of working on page refresh, and not needing an extra network request
Here's a simple example from one of my apps, error handling left out for simplicity, so use with caution
angular.
module('alienstreamApp')
.service('api', ['$http', '$q','$window', function($http, $q, $window) {
//meta data request functions
this.trending = function() {
}
this.request = function(url,params) {
var differed = $q.defer();
var storage = $window.localStorage;
var value = JSON.parse(storage.getItem(url+params))
if(value) {
differed.resolve(value);
} else {
$http.get("http://api.alienstream.com/"+url+"/?"+params)
.success(function(result){
differed.resolve(result);
storage.setItem(url+params,JSON.stringify(result))
})
}
return differed.promise;
}
}]);
I would say that you should start off simple and do a new server call when you hit the new route. My experience is that this simplifies development and you can put your effort on optimizing performance (or user experience...) where you will need it the most.
Something like this:
angular.module('app', ['ngRoute', 'ngResource'])
.factory('Users', function ($resource) {
return $resource('/api/Users/:userid', { userid: '#id' }, {
query: { method: 'GET', params: { userid: '' }, isArray: true }
});
});
.controller("UsersController",
['$scope', 'Users',
function ($scope, Users) {
$scope.loading = true;
$scope.users = Users.query(function () {
$scope.loading = false;
});
}]);
.controller("UserController",
['$scope', '$routeParams', 'Users',
function ($scope, $routeParams, Users) {
$scope.loading = true;
$scope.user = Users.get({ userid: $routeParams.userid }, function () {
$scope.loading = false;
});
$scope.submit = function () {
$scope.user.$update(function () {
alert("Saved ok!");
});
}
}]);
.config(
['$routeProvider', '$locationProvider',
function ($routeProvider, $locationProvider) {
$routeProvider
.when('/users', {
templateUrl: '/users.html',
controller: 'UsersController'
})
.when('/users/:userid', {
templateUrl: '/user.html',
controller: 'UserController'
})
.otherwise({ redirectTo: '/users' });
}
]
);

AngularJS service only running the first time controller is used

I have the following controller that uses a service Customers to return customers. The problem is that its only executing the service the first time the controller is run. Looking at my server I see its only performing the get request the FIRST time the controller used(loading that view) if I change views and say add a customer and come back to the view that list customers its not updated because there was not another get request from the service.
.controller('searchCTRL', ['$scope', '$http', 'Customers', function($scope, $http, Customers) {
$scope.customers = Customers;
$scope.deleteCustomer = function(id) {
$http.delete('/api/customer/' + id)
.success(function(data) {
$scope.customers.data = data;
})
.error(function(data) {
console.log('Error: ' + data);
});
};
}])
and
.factory('Customers', function($http){
var Customers = {};
$http.get('/api/customer')
.success(function(data) {
Customers.data = data;
})
.error(function(data){
console.log('error: ' + data);
});
return Customers;
});
if I stay on the view and reload the page it gets the data like it should but any subsequent visits to the page no longer execute the get. Any help would be appreciated.
Angular .factory is a singleton so it will always only run once. Also, the $http call is async so you should be using promise in order to get the data to your controller. Try the following:
.factory('Customers', function($http, $q){
return function () {
var d = $q.defer();
$http.get('/api/customer')
.success(function(data) {
d.resolve(data);
})
.error(function(data){
console.log('error: ' + data);
d.reject(data);
});
return d.promise;
};
});
and in your controller:
.controller('searchCTRL', ['$scope', '$http', 'Customers', function($scope, $http, Customers) {
Customers().then(function (data) {
$scope.customers = data;
});
...
As $http returns a promise, you can further simply your .factory by doing:
.factory('Customers', function($http){
return function () {
return $http.get('/api/customer');
};
})
For more detail, see documentation for $http.

Categories

Resources