Tips for saving data fetched from a $resource into localStorage?

After utilizing my service to parse RSS with googleapis, it returns an array's Object that contains other Objects. Upon checking the chrome console, I see the following output:

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

However, when trying to retrieve data in my controller using localStorage, the console only displays brackets or nothing at all:

$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']));

Output :

TEST : []
TEST : 
TEST : 

What could be the issue here?

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;
    };
})

Answer №1

The issue at hand is that FeedList.get() relies on asynchronous operations, causing $scope.feeds to not be immediately populated.

To address this problem, consider the following solution:

$scope.feeds = FeedList.get();
$scope.feeds.then(function () {
    // Loading of $scope.feeds is now complete
    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']));
});

Note: Upon reviewing the code for your service, it appears that it does not return a promise. To enable consumers of your service to wait for results, you must implement this feature:

.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;
    };
})

Answer №2

The issue arises from insufficient handling of asynchronous requests. In order to rectify this:

$scope.feeds = [];

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

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);
    };
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps for Loading Image after Preloader:1. Set up a preloader

My goal is to have the current thumbnail image passed to the #big-image div and shown with a pre-loader when the page-gallery--thumbnails li class is clicked. However, the current code is not meeting my expectations as the image loads before the pre-loader ...

Accessing JSON data from a URL in AngularJS

Just dove into the world of fetching and displaying JSON data in my AngularJS app for the first time, but unfortunately, no data is showing up. Here's the code I have implemented: HTML <div ng-app="myApp" ng-controller="custom ...

As for the Pixel Art Creator feature, you can now switch between different modes and

I'm seeking assistance regarding my Pixel Art Maker project. I recently implemented two new features, toggle() and remove(). The issue I'm facing is that when I input numbers to create the grid and click the submit button, the grid is successfull ...

Is executing JavaScript possible within the <script src="..."></script> tags?

I have a JavaScript file that handles tab switches, here is the code: var numTabs = 0; function SwitchTab(tabId) { if (tabId < 0 || tabId > numTabs) { tabId = 0; } for (var i = 0; i < numTabs; i++) { document.getElementById("tab" + i).c ...

Use AngularJs service injected in run closure for testing purposes

Testing an angularjs service called MyService has been a bit challenging. It seems like Angular tries to use the service before it is fully loaded when I try to inject it directly. However, if I mock MyService using $provide, it does work but then I don&ap ...

Iterate through a modified list in Vue.js using a parameter

Is there a more efficient way to iterate through a filtered list with a given input parameter in vue.js? I want to avoid using filtering within the template like <li v-for="x in todos_filtered" v-if="x.person == 'Mike'"> ...

Tips for testing a directive that binds data from a controller

I've created a directive that simply converts the text from the controller to uppercase. For some reason, my unit test code is not working. Any suggestions? Here's the html: <div ng-controller="MainCtrl as main"> <div uppercase&g ...

How can one easily remove the parent directory from a path when working with Node.js?

If the path is /foo/bar/baz.json and I need only /bar/baz.json, how can this be achieved using Node.js's path functionality? ...

Interfacing Node JS with Java Web Services via SOAP

I've been attempting to connect Java web services from a Node.js module, but I'm encountering an error in the wsdl library. Below is my wsdl file: <!-- Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130 ...

What is the best method for securely transferring login credentials from foo.com to bar.com?

I currently manage two websites, and . The actual application resides on bar.com, but clients prefer applicants to log in through foo.com. In the past, I have logged in at www.bar.com, but now I am looking to implement a secure form on foo.com that allows ...

What is the best way to assign a unique ID to every element in this situation?

Here is the given code: var words = ['ac', 'bd', 'bf', 'uy', 'ca']; document.getElementById("wordTable").innerHTML = arr2tbl(2); function arr2tbl(ncols) { return words.reduce((a, c, i) => { ...

I am seeking to incorporate several Three.js animations into my HTML document, but I am experiencing issues with them

As a professional graphic designer, I am facing an issue with Three.js https://i.sstatic.net/6ZsWa.jpg I have tried several solutions, but none seem to work effectively. In my attempt, I duplicated the imported model and changed its name. Despite trying ...

Accessing Angular scope values from a different function within the same controller may not be possible due to encapsulation

Why am I unable to access the $scope value in my Angular controller from one function to another? Initially, it seemed like it should work because they are both within the same controller. However, I'm encountering an issue where the variable is undef ...

Unable to reload kendo data grid by clicking a button in AngularJS

Currently, I am facing an issue with the kendo grid used in angularjs. The grid loads perfectly on page load, but when I try to refresh it by hitting the search button with new search criteria, it fails to display the updated data. Here is the snippet of ...

Discover the power of combining Go with Angular's ui-router to

A novice Gopher here, working on establishing a Go backend to support my Angularjs frontend as well as an API. This is the progress I've made so far: package main import ( "github.com/gorilla/mux" "log" "net/http" ) func main() { r ...

Instructions for developing an offset plugin for an HTML5 video player

I'm currently working on developing an offset plugin that allows playing a specific portion of a video in an HTML5 video player. While there is an existing plugin for video.js available at videojs-offset plugin, I am now experimenting to adapt this p ...

Working with arrays and elements in JavaScript using regular expressions

The programming language is JavaScript. Imagine we have an array filled with positive and negative integers mixed in with other letters (e.g. 1a or -2d). The challenge is to figure out how to select all the strings that start with or contain positive inte ...

Tips on efficiently adding and removing elements in an array at specific positions, all the while adjusting the positions accordingly

My challenge involves an array of objects each containing a position property, as well as other properties. It looks something like this: [{position: 1, ...otherProperties}, ...otherObjects] On the frontend, these objects are displayed and sorted based on ...

Passing props down in Next.js when working with children components

Within my Next js page, I have a component structured as follows: ... <Chart isShoppingChartOpen={isShoppingChartOpen} toggleShoppingChart={toggleChartVisibility} lineItems={lineItems} /> <main className= ...

Utilizing Next.js to conditionally display data

My current challenge involves rendering data fetched from an API. The data is in JSON format, and I have a conditional logic to push a specific element based on the fetch result. {status: 'success'} If the fetch fails, I need to handle it by pus ...