Mad
Mad

Reputation: 548

Angularjs get object values outside of function

I need to get localeData value print out side of below function. I know how to print in side of function like what i did here. I have tried this but didn't work.

    $http.post(SERVER_URL + 'getLocaleData').success(function(localeData) {
        console.log(localeData);
        }).error(function(err) {
            alert('warning', err.message);
        });
        //need to get that value here.
        console.log(localeData);

EDIT

Actually i need to do is this

app.factory('customLoader', function($http, $q, SERVER_URL) {

    return function(options) {
        var deferred = $q.defer();

        // do something with $http, $q and key to load localization files
        $http.post(SERVER_URL + 'getLocaleData').success(function(localeData) {
         //do something here to localData
        }).error(function(err) {
            alert('warning', err.message);
        });

        deferred.resolve(localeData);
        return deferred.promise;

    };
});

This is what i need. finally i need to send localeData.

Upvotes: 0

Views: 1457

Answers (5)

Igwe Kalu
Igwe Kalu

Reputation: 14868

You don't need $q to accomplish your objective:

app.factory('customLoader', ["$http", "SERVER_URL", function($http, SERVER_URL) {
    return function(options) {
        return $http.post(SERVER_URL + 'getLocaleData');
    };
}]);

Because $http and all it's convenience methods actually return a promise. In this case, you can use this service as follows:

customLoader(options).success(function(localeData){
    //do something here to localData
}).error(function(err){
    alert('warning', err.message);
});

If you really must use $q, then this should do:

app.factory('customLoader', ["$http", "$q", "SERVER_URL", function($http, $q, SERVER_URL) {
    return function(options) {
        return $q(function(resolve, reject){
            $http.post(SERVER_URL + 'getLocaleData').success(function(localeData) {
                //do something here to localData
                resolve(localeData); // ultimately you ought to resolve inside this function
            }).error(function(err) {
                alert('warning', err.message);
                reject(localeData); // ultimately you ought to reject inside this function
            });
        });
    };
}]);

Upvotes: 0

nalinc
nalinc

Reputation: 7425

localeData is limited to the scope of .success function. You cant get it outside unless you assign it some other variable.

var data = ""
$http.post(SERVER_URL + 'getLocaleData').success(function(localeData) {
    data = localeData;
    }).error(function(err) {
        alert('warning', err.message);
    });
//need to get that value here.
console.log(data);

But dont expect to get the desired value in data until you get the response back. $http.post is async

Take a look at promises to overcome such issues, because they are used all over the place, in angular world.

UPDATE:

As you have done in the edit, you may either use $q service like:

app.factory('customLoader', function($http, $q, SERVER_URL) {

    return function(options) {
        var deferred = $q.defer();

        // do something with $http, $q and key to load localization files
        $http.post(SERVER_URL + 'getLocaleData').success(function(localeData) {
         //do something here to localData
        }).error(function(err) {
            alert('warning', err.message);
        });

        deferred.resolve(localeData);
        return deferred.promise;

    };
});

OR, you may simply return $http.post which itself returns a promise

app.factory('customLoader', function($http, $q, SERVER_URL) {
    return function(options) {        
        return $http.post(SERVER_URL + 'getLocaleData');
    };
});

In either way, you are returning a promise object and not just the actual response you get from server. The localeData can be accessed as follows:

customLoader().success(function(res){
   console.log(res);
 }).error(function(){
    //show some error message
 })

Upvotes: 0

Umut Benzer
Umut Benzer

Reputation: 3526

You don't need to create & resolve a defer yourself. There is an easier way. (Also in the example you give, you resolve promise before the underlying ajax completed)

Angular.js $http service follows $q interface too! So you can write:

app.factory('customLoader', function($http, $q, SERVER_URL) {
  return function(options) {
    var promise = $http.post(SERVER_URL + 'getLocaleData')
      .then(function(localeDataBag) {
         var localeData = localeDataBag.data; // .data of 'then' equals to what .success returns.            
         modifiedLocaleData = localeData++;  // do something here to localData
         return modifiedLocaleData; // This is the new result
        })
      .catch(function(err) {
        console.log(err);
        return $q.reject(err); // This is the new result if something failed. Since we are chaining promises, we should keep failure state.
      });
    return promise;
  };
});

Upvotes: 1

Saurabh Palatkar
Saurabh Palatkar

Reputation: 3384

By following way you can access your server response outside factory in the controller:

app.factory('customLoader', function ($http, $q) {
        return {
            response: {},
            getLocalData: function (param) {
                var deferred = $q.defer();
                $http.post(SERVER_URL + 'getLocaleData', param).
                    success(function (data, status, headers, config) {
                        deferred.resolve(data);
                    }).
                    error(function (data, status, headers, config) {

                    });

                return deferred.promise;
            }
        }
    });


 app.controller('yourCtrl', function($scope,customLoader) {

       $scope.GetLocaleData= function() {    
                customLoader.getLocalData({
                    Role: role,
                    Email_Id: $scope.Email,
                    Pwd: $scope.Password
                }).then(function(localeData) {
                    $scope.Data = localeData;                        
                });        
        }
 }); 

Upvotes: 0

rdiz
rdiz

Reputation: 6176

JS is asynchronous, which basically means that your last console.log will be executed before your server returned any data. So you have to do it inside both your promises:

$http.post(SERVER_URL + 'getLocaleData').success(function(localeData) {
    console.log(localeData);
    }).error(function(err) {
         console.log(err);
        alert('warning', err.message); //Just in case you didn't know, this line supposes that your server returns a JSON object with a "message"-property

    });

That way, your server-response will be console.log'ed both on success and failure.

Reference

Edit: If you really wanna do it the other way:

var response; //First, declare a variable in the parent scope.

$http.post(SERVER_URL + 'getLocaleData').success(function(localeData) {
    response = localeData; //Assign the response data to the variable.
    console.log(localeData);
    }).error(function(err) {
        alert('warning', err.message); //Just in case you didn't know, this line supposes that your server returns a JSON object with a "message"-property

    });
    console.log(response);

The example won't evaluate as you expect, though. The last console.log will just log undefined.

Upvotes: 0

Related Questions