Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting and getting data value from service in Angular JS

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.

like image 725
geekchic Avatar asked Nov 27 '25 17:11

geekchic


1 Answers

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;
});
like image 112
dfsq Avatar answered Nov 29 '25 08:11

dfsq



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!