Setting and getting data value from service in Angular JS

So this is my service that I am using to get 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 that works great when I receive 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 running this function in Controller 1

I will try to do the following in Controller 2

:

$scope.userData = userDetailService.userData;
console.log($scope.userData); //Prints null

      

But $scope.userData

it is null. Isn't that the purpose of using a data exchange service between controllers? Since I've already set the value userData

to Controller 1

, shouldn't I be able to access it in Controller 2

?

Oddly enough, a modal dialog that is a template for Controller 2

can access data in a form {{userData.first_name}}

or {{userData.last_name}}

. If this works, why $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 boxes.

+3


source to share


1 answer


Your approach is not very reliable as you cannot be 100% sure that the data has already been loaded when you try to access it in a second controller. Instead of assigning custom data to a variable, always call a method getUserDetails

that returns a promise. Then you just need to cache the loaded data to avoid duplicate 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
    }
});

      

The wrapper userData

in $q.when

creates a promise object that resolves immediately. This is what you want as the service API is now consistent - you are always dealing with promises.



Usage in both controllers would be as follows:

userDetailService.getUserDetails(userId).then(function(data) {
    $scope.userData = data;
});

      

+2


source







All Articles