Why does angular $resource add extra objects ($promise, $resolve…) to my data response?

I return a resource with a URL

    $resource("http://foo.com/bar.json").get().
         $promise.then(function(data){ $scope.result = data}, 
                  function(error){ $scope.msg = "error" } );

Resource returns

["item1"...."item_n",.....,"$promise", "$resolved", "$get", "$save", "$query", "$remove", "$delete"]

Why do I get all those objects in my data set. I’m guessing $promise just returns all this and waits for the server response. But once I have the server response where can I just get my server data without the Promise jargon?

Here is Solutions:

We have many solutions to this problem, But we recommend you to use the first solution because it is tested & true solution that will 100% work for you.

Solution 1

If you look at the angular source here:

https://github.com/angular/angular.js/blob/master/src/ngResource/resource.js#L505

There is a toJSON method on the Resource prototype chain that will accomplish this for you.

For example:

$resource("http://foo.com/bar.json").get(function(res) {
    $scope.result = res.toJSON();
});

Solution 2

You need to return wrapped result like {‘result’: { ‘some_key’: ‘some_val’ }} from your backend.
Or just do like described above.

Diary.getSharedWithMe(function(data) {
        delete data.$promise;
        delete data.$resolved;
        _self.sharedDiariesWithMe = data;
    }, function(error) {
        console.log(error)
    });

Solution 3

$resource returns an object or array that will have your data when the call completes. All those functions are there to help you out and $resource is mainly intended for CRUD operations. If you want the data, you have to wait for it to get returned so you might as well use the promise. If you want to strip all of those properties you can use angular.toJson to convert it to json, but angular does that for you when posting it back to a resource or $http call so you shouldn’t have to.

$scope.data = $resource("http://foo.com/bar.json").get();
// $scope.data does not have your data yet, it will be
// populated with your data when the AJAX call completes
...
// later in a call from a save button maybe you can just do
// this to post your changes back:
$scope.data.$save();

Solution 4

So in case someone else is stumbling here and didn’t understand promises/angularjs here is what is going on. When you use .then() or .get() you get a promise and some helper functions all in the same object. This is awesome because then you don’t worry about callbacks being defined and whether data is available because the promise object always has some properties. This object contains your raw data in another object within. So the promise object is nested, you just have to reference the data object within when the data is ready.

Here’s what I was doing

     $resource("http://foo.com/bar.json").get().
         $promise.then(function(data){ $scope.result = data}, 
//data is actually a promise object.
                  function(error){ $scope.msg = "error" } );

promise object

enter image description here

Note the data is actually under another object called “data”. So in your success callback to get just the data you should do in this case: data.data

Solution 5

To automatically remove them from every request, you can add an interceptor:

angular.module('app').config(config);

config.$inject = ['$httpProvider'];
function config($httpProvider) {
    $httpProvider.interceptors.push(interceptor);
}

interceptor.$inject = [];
function interceptor() {
    return {
        request: (config) => {
            if (config.data) {
                delete config.data.$promise;
                delete config.data.$resolved;
            }
            return config;
        }
    };
}

Note: Use and implement solution 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply