Reputation: 45
Hi I've create an application angular, I would login user with a call http get to WS Java. I use a view in angular, to pass parameters between views i use a factory.
My code: I create angular module
angular.module('contactMgr',['ngRoute'])
.controller('AppCtrl',['$scope',function ($scope){}])
.config(['$routeProvider','$locationProvider',
function($routeProvider,$locationProvider){
$routeProvider.when('/',{
controller: 'homePageCtrl',
templateUrl: 'assets/partials/homePage.html'
})
.when('/login',{
controller: 'loginCtrl',
templateUrl: 'assets/partials/login.html'
})
.when('/loginError',{
controller: 'loginErrorCtrl',
templateUrl: 'assets/partials/loginError.html'
});
}])
Then add controller for login that call WS to execute login. If the WS response ID i call method load in a factory to load the user, and finally i redirect to home page
.controller('loginCtrl',['$scope','$http','$location','UserLogged',
function($scope,$http,$location,UserLogged){
$scope.loginFunction = function(){
$http({method: 'GET',
url: 'http://localhost:8080/TaskManagerWS/login/'+$scope.lg_email+':'+$scope.lg_password
}).then(function success(data,status,xhr){
$scope.idUser = data.data;
if($scope.idUser!=0){
UserLogged.load($scope.idUser);
$location.path("/");
}
else{ $location.path("/loginError"); }
},
function error(data,status,xhr){ alert("Error on call function!"); }
);
};
}])
my factory to load user
.factory('UserLogged',['$http',function($http){
var userLogged;
return{
load: function(id){
$http({
method: 'GET',
url: 'http://localhost:8080/TaskManagerWS/user/id='+id
}).then(function success(data,status,xhr){
userLogged = data.data;
},
function error(data,status,xhr){
window.alert("Error on call function!");
}
);
},
get: function(){
return userLogged;
}
}
}])
And finally my controller for home page
.controller('homePageCtrl',['$scope','UserLogged',function($scope,UserLogged){
$scope.user = UserLogged.get();
}])
All call working fine but, when i redirect to home page I don't see the result.
My home page are only tag "h1" with {{user.name}}.
But if i navigation navbar and change view and then i return to home page the title see.
Why this behavior? I would load immediately factory.
I think that angular before load page and then load factory. There is any instruction to load before factory and then page?
I try to put in the var userLogged on factory a static string and then work fine, the title load immediately. Maybe the time problem are in the $http call.
There is any method to reload view after the response of $http service?
Thanks
SOLVED:
Thanks @Matthew Cawley
I change my loginCTRL and add
UserLogged.loadCall($scope.idUser).then(function success(data,status,xhr){
UserLogged.loadFactory(data.data);
$location.path("/");
},
function error(data,status,xhr){
window.alert("Error on call function!");
}
);
}
and then i change factory to return $http in the method load and finally i add method to loadFactory to load userLogged.
There is a solution that i don't really like, but seems is the only.
Upvotes: 1
Views: 729
Reputation: 2818
It looks like you're redirecting to the home page to soon, i.e. before the UserLogged
service has finished loading and set it's ownuserLogged
variable to the data returned by the $http
call.
This means that when you call $scope.user = UserLogged.get();
in your homePageCtrl
it goes straight to the service's get
method and returns nothing (because at this point userLogged
hasn't been set).
Then, moments later (without really noticing it)... the $http
call completes and the userLogged
variable becomes set with the results but it's too late.
Solution 1: Return a promise to use in the controller
Return the promise created by the $http
service by adding the return
keyword:
load: function(id){
return $http({
method: 'GET',
url: 'http://localhost:8080/TaskManagerWS/user/id='+id
})
and then in your loginCtrl
, change:
UserLogged.load($scope.idUser);
$location.path("/");
to:
UserLogged.load($scope.idUser)
.then(function(){
$location.path("/");
});
This way you'll only get redirected once the UserLogged.load()
method has carried out it's work.
Solution 2: Pass a callback function into the service (or factory).
Create a function in loginCtrl
that does a redirect:
var redirectToHome = function(){
$location.path("/");
}
Then add an extra callback
parameter to the service's load()
function, and execute that callback
function when the promise is resolved in the service (after userLogged has been set):
load: function(id, callback) { // <---- Add extra "callback" parameter
$http({
method: 'GET',
url: 'http://localhost:8080/TaskManagerWS/user/id='+id
}).then(function success(data,status,xhr){
userLogged = data.data;
callback(); // <---- Execute the callback function (whatever it contains)
},function error(data,status,xhr){
window.alert("Error on call function!");
});
}
Then in the loginCtrl
when you call services login
function, do so by passing in a reference to the redirectToHome
function as the callback as follows:
UserLogged.load($scope.idUser, redirectToHome); // <--- redirectToHome becomes the callback.
Upvotes: 1