0

So i have a bit of a confusion with angular promises.

I have a service, storing a list of users

.service('user', ['$q','$http', function ($q, $http) {
 var services = {};

 var _def_userLsit = $q.defer();

 $http.get('/api/acc/getlist').then(function (data) {
    _def_userLsit.resolve(data);
 })

 services.getUserListQ = function () {
    return _def_userLsit.promise;
 }
 return services;
}])

after injecting it, i can load my list like this in a controller:

            user.getUserListQ().then(function (promise) {
            $scope.userHelper.userList = promise.data;
        });

no problem here, got the json in the $scope, then the watchers do their jobs just fine.

Here is the Json format simplified for the question:

obj 1 { id=4, userName="foohuman", $$hashKey="object:14"} obj 2 { id=444, userName="barhuman", $$hashKey="object:22"}

But i also want a user's name by id, and i need to run that several times ( depend on the post count ).

So my question here is, how can i return a user's name like a function call, from that promised list.

like a normal function would do, like this:

$scope.getUserById = function(  id ){
  return "foo";
  //some magic needed here
}

If i just iterate trough the userHelper.userList, it could be empty if it runs too early, so i need to load that trough a promise, but loading it, iterating trough, then adding a string to the $scope is not the best options, since it can run multiple times, so it can overwrite each other, pretty unpredictably if i store it in a single variable.

So any idea how can i return a nice simple string by the id, and not a promise?

EDIT: Ok, so i can't really return a nice string, because it have to be some kind of callback, but i can process the data from the promise, so i ended up loading user data into a array like this:

 user.getUserListQ().then(function (promise) {

           var uArr = [];
           angular.forEach(promise.data, function ( value, key ) {
               uArr[value.id] = value.userName;
           })

           $scope.userHelper.uArr = uArr;

        });

and in the html I can boldly write {{userHelper.uArr[taskData.tOwner]}}.

MrKekson
  • 720
  • 6
  • 18

1 Answers1

1

First of all, you're making promises harder than they should be by using the explicit construction antipattern. Your first code snippet can be replaced with this:

.service('user', ['$q','$http', function ($q, $http) {
    var services = {};

    var pUserList = $http.get('/api/acc/getlist');

    services.getUserListQ = function () {
        return pUserList;
    };

    return services;
}]);

Regarding your question:

So any idea how can i return a nice simple string by the id, and not a promise?

This is the wrong mindset to have. For getting a user by their ID, you need to think in terms of promises. You don't know exactly when the data is going to be ready, so this means that your getUserId method should return a promise. You can write it like this:

services.getUserById = function (id) {
    return pUserList.then(function (users) {
        return users.filter(function (user) { return user.id === id; })[0];
    });
};

in your controller, you can use it like this:

myService.getUserById(4).then(function (user) {
    $scope.myUser = user;
});
Community
  • 1
  • 1
JLRishe
  • 99,490
  • 19
  • 131
  • 169