So this is my service that I use to fetch user details.
angular.module('app')
.factory('userDetailService', function($http) {
var userData = {};
function getUserDetails(userId) {
if (userId) {
return $http.get("/users/" + userId).success(function(data) {
angular.copy(data[0], userData);
});
}
}
return {
userData: userData,
getUserDetails: getUserDetails
}
})
Now in Controller 1 that uses this service, I have this bit of code which works fine as I get the relevant data.
$scope.getUserId = function(userId) {
if (userId) {
$scope.userData = userDetailService.userData;
userDetailService.getUserDetails(userId).success(function() {
console.log($scope.userData); //Prints valid user data
});
}
};
After this function executes in Controller 1, I try to do the following in Controller 2:
$scope.userData = userDetailService.userData;
console.log($scope.userData); //Prints null
But $scope.userData is null. Isn't the whole purpose of using a service to share data between controllers? Since I have already set the value of userData in Controller 1, shouldn't I be able to access it in Controller 2?
Weirdly enough, the modal dialog which is the template for Controller 2 is able to access data in the form of {{userData.first_name}} or {{userData.last_name}}. If this works, why is $scope.userData null? What am I missing?
Edit:
Template 1:
<div id="myModal" ng-controller="Controller 1">
<modal-configure-user></modal-configure-user>
<a data-toggle="modal" data-target="#configureUserModal" href="#" ng-click="getUserId(user.id)" data-id="user.id">{{user.first_name + ' ' +user.last_name}}</a>
</div>
Template 2:
<div ng-controller="Controller 2" id="configureUserModal">
</div>
Both are modal dialog windows.
Your approach is not very reliable, since you can't be 100% sure that data has already loaded when you try to access it in the second controller. Instead of assigning user data to variable always invoke getUserDetails method, which returns a promise. Then you just need to cache loaded data to avoid duplicated requests.
angular.module('app')
.factory('userDetailService', function($q, $http) {
var userData;
function getUserDetails(userId) {
if (userId) {
return userData ? $q.when(userData) : $http.get("/users/" + userId).success(function(data) {
userData = data;
return userData;
});
}
}
return {
getUserDetails: getUserDetails
}
});
Wrapping userData into $q.when creates a promise object, which resolves immediately. This is what you need, because service API is now consistent - you always deal with promises.
The usage in both controller then would be:
userDetailService.getUserDetails(userId).then(function(data) {
$scope.userData = data;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With