Angular.js resourceProvider возвращает $ обещание с данными

Данный сервис angular.js:

angular.module('mymodule').factory('Products', ['$resource',
    function($resource) {
        return $resource('/path/to/getProducts', {}, {
            find: {
                method: 'GET',
                isArray: false
            }
        });
    }
]);

В контроллере mymodule я делаю find запрос:

$scope.findAll = function () {
    Products.find(function (products) {
        console.log(Object.keys(products));
        // ['prodA', 'prodB', ... , '$promise', '$resolved']
        for (var i in products) {
            if (!products.hasOwnProperty(i)) continue;
            console.log(products[i].description.someprop);
            // Got error: Cannot read property 'someprop' of undefined
            // Trust me: I debug this place. someprop is defined for all items except that two
        }
    });
};

Он работает нормально, но возвращает $ обещание и $ разрешено с набором данных, так что я не могу перебрать свои данные.

Угловая документация говорит о том, что Resource экземпляры и коллекция имеют эти дополнительные свойства. Но я не понимаю, как именно это контролировать в моем коде.

Что я делаю неправильно? Как это предотвратить?

4 ответа

Решение

На самом деле это немного сложнее, когда вы не работаете с массивами.

response Объект, отправленный обратно с сервера, содержит:

  • resource объект (ваши данные + $promise а также $resolvedвот что ты получаешь в своем обратном звонке)
  • config объект (заголовки, используемый метод, вызываемый URL и т. д.) и headers функция
  • и data объект, это то, что мы хотим! Он содержит только данные.

Но вы только увидите response.resource в вашем then(), Поэтому вам необходимо перехватить ответ, отправленный сервером, чтобы получить данные:

return $resource('/path/to/getProducts', {}, {
        find: {
           method: 'GET',
           isArray: false,
           interceptor: {
             response: function(response) {  
               return response.data;
             }
           }
        }
    });

И тогда в вашем контроллере:

Products.find().$promise.then(
    function(products){
        angular.forEach(products, function(value, index){
            console.log(value);
        });
    }
);

Скажи мне, если это работает для тебя.

Plunker Demo

Я полагаю, ваша проблема - isArray: false. Так что ваши продукты - это не массив, а объект. Установите isArray: true, и вы можете выполнять итерацию для (var product in products) весь день.

Ресурсы возвращают обещание, вы можете получить данные из обещания, используя then(),

Products.find().$promise.then(function (products) {
    console.log(Object.keys(products));
});

Попробуйте сделать response.toJSON, и он вернет только ваш json, исключая обещание и разрешение.

data.$promise.then(function(myResponse) {
    var actualData = myResponse.toJSON();
}
Другие вопросы по тегам