简体   繁体   中英

How to store values retrieved from a $resource in localStorage?

My service parsing RSS with googleapis and returns a array's Object containing others Objects. Below, the chrome console ouput :

[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]
   0: Object
   1: Object
   2: Object
   3: Object

But in my controller cannot use localStorage to retrieve data, the console output return only bracket or nothing :

$scope.feeds = FeedList.get();
window.localStorage.setItem('savedData', JSON.stringify($scope.feeds));

console.log('TEST : ' + window.localStorage['savedData']);
console.log('TEST : ' + JSON.parse(window.localStorage.getItem('savedData')));
console.log('TEST : ' + JSON.parse(window.localStorage['savedData']));

Ouput :

TEST : []
TEST : 
TEST : 

Please, what is wrong ?

service.js

.factory('FeedLoader', function ($resource) {
        return $resource('http://ajax.googleapis.com/ajax/services/feed/load', {}, {
            fetch: { method: 'JSONP', params: {v: '1.0', callback: 'JSON_CALLBACK'} }
        });
    })

.service('FeedList', function ($rootScope, FeedLoader) {
    var feeds = [];
    this.get = function() {
        var feedSources = [
            {title: 'rss1', url: 'http://www.website.com/rss/feed/rss_feed_25300'},
            {title: 'rss2', url: 'http://www.website.com/rss/feed/rss_feed_10720'},
        ];
        if (feeds.length === 0) {
            for (var i=0; i<feedSources.length; i++) {
                FeedLoader.fetch({q: feedSources[i].url, num: 10}, {}, function (data) {
                    var feed = data.responseData.feed;
                    console.log(feed.entries);
                    feeds.push(feed.entries);
                });
            }
        }
        return feeds;
    };
})

What's wrong is that FeedList.get() uses asynchrony and $scope.feeds will not be populated right away.

Try this:

$scope.feeds = FeedList.get();
$scope.feeds.then(function () {
    // $scope.feeds is done loading now
    window.localStorage.setItem('savedData', JSON.stringify($scope.feeds));

    console.log('TEST : ' + window.localStorage['savedData']);
    console.log('TEST : ' + JSON.parse(window.localStorage.getItem('savedData')));
    console.log('TEST : ' + JSON.parse(window.localStorage['savedData']));
});

Edit: Now that you've provided the code for your service, it's clear that it doesn't return a promise. You need to do that in order for the consumers of your service to be able to wait on the results:

.service('FeedList', function ($rootScope, $q, FeedLoader) {
    var feeds;
    this.get = function() {
        var feedSources = [
            {title: 'rss1', url: 'http://www.website.com/rss/feed/rss_feed_25300'},
            {title: 'rss2', url: 'http://www.website.com/rss/feed/rss_feed_10720'},
        ];

        if (!feeds) {
            var feedPromises = feedSources.map(function (source) {
                return FeedLoader.fetch({q: source.url, num: 10}, {}).$promise
                .then(function (data) {
                    return data.responseData.feed.entries;
                });
            });

            feeds = $q.all(feedPromises)
            .then(function (retrievedFeeds) {
               return Array.prototype.concat([], retrievedFeeds);                
            });
        }
        return feeds;
    };
})

The problem is that you don't handle async request properly, so:

$scope.feeds = [];

console.log('TEST : Load feeds async');

FeedList.get().then(function () { // each feed comes as argument
    angular.forEach(arguments, function (feed) {
        $scope.feeds.concat(feed); // merge arrays
    });

    window.localStorage.setItem('savedData', JSON.stringify($scope.feeds));

    console.log('TEST : ' + window.localStorage['savedData']);
    console.log('TEST : ' + JSON.parse(window.localStorage.getItem('savedData')));
    console.log('TEST : ' + JSON.parse(window.localStorage['savedData']));
});

Service:

.service('FeedList', function ($q, $rootScope, FeedLoader) {
    this.get = function () {
        var promises = []; // to handle async loading 

        var feedSources = [{
            title: 'rss1',
            url: 'http://www.website.com/rss/feed/rss_feed_25300'
        }, {
            title: 'rss2',
            url: 'http://www.website.com/rss/feed/rss_feed_10720'
        }];

        angular.forEach(feedSources, function (source) {
            var defer = $q.defer();

            FeedLoader.fetch({
                q: source.url,
                num: 10
            }, {}, function (data) {
                var feed = data.responseData.feed;
                defer.resolve(feed.entries); // todo - need to handle errors with 'defer.reject'
            });

            promises.push(defer.promise);
        });

        return $q.all(promises);
    };
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM