Create a basic cache within an AngularJS service to store data retrieved from HTTP requests, ensuring that the cache returns an object

Looking to implement a simple caching mechanism in an AngularJS service for data retrieved from HTTP requests. The goal is to always reference the same object to avoid duplicating requests. Below is an example code snippet showcasing the issue at hand.

Link to the JSFiddle code illustrating the problem

The UsersModel service fetches user data via HTTP requests, with this data being shared across controllers. The aim is to maintain a consistent reference to the data. A check is added before calling UsersModel.getUsers() to see if any cached data exists; if not, a new request is made. This service is then injected into three different controllers. The first two controllers make the call immediately upon page load, while the third does so upon button click. The issue arises when the first two controllers simultaneously trigger the UsersModel.getUsers() function, resulting in separate HTTP requests and referencing different user objects.

The question is how to ensure that simultaneous calls to UsersModel.getUsers() return the same data object consistently.

app.js

var APP = angular.module('APP', []);
APP.SidebarCtrl = function ($scope, UsersModel) {
    var sidebarCtrl = this;

    UsersModel.getUsers()
        .then(function (users) {
            sidebarCtrl.users = users;
        });
};
APP.ContentCtrl = function ($scope, UsersModel) {
    var contentCtrl = this;

    UsersModel.getUsers()
        .then(function (users) {
            contentCtrl.users = users;
        });
};
APP.FootCtrl = function ($scope, UsersModel) {
    var footCtrl = this;

    function load() {
        UsersModel.getUsers()
            .then(function (users) {
                footCtrl.users = users;
            });
    }

    footCtrl.load = load 
};

APP.service('UsersModel', function ($http, $q) {
    var model = this,
        URLS = {
            FETCH: 'http://api.randomuser.me/'
        },
        users;

    function extract(result) {
        return result.data.results['0'].user.email;
    }

    function cacheUsers(result) {
        users = extract(result);
        return users;
    }

    model.getUsers = function () {
        return (users) ? $q.when(users) : $http.get(URLS.FETCH).then(cacheUsers);
    };
});   

Index.html

<div ng-app="APP">
    <div ng-controller="APP.SidebarCtrl as sidebarCtrl">
        <h1>{{ sidebarCtrl.users }}</h1>
    </div>
    <div ng-controller="APP.ContentCtrl as contentCtrl">
        <h1>{{ contentCtrl.users }}</h1>
    </div>
    <div ng-controller="APP.FootCtrl as footCtrl">
        <h1>{{ footCtrl.users }}</h1>
         <button ng-click="footCtrl.load()" type="button">Load</button> 
    </div>
</div>

Link to the JSFiddle code illustrating the problem

Answer №1

To enhance your functions, you can make the following adjustments:

function updateCache(result) {
    return (cachedData) ? cachedData : cachedData = extract(result);
} 

Also,

database.retrieveData = function () { 
    return (cachedData) ? $q.when(cachedData) : $http.get(URLS.FETCH, {cache: true}).then(updateCache); 
}; 

This code includes an additional cache validation step after fetching data and activates the built-in cache feature for the object.

I recommend taking a look at for further insights.

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

Error: Unable to split function. Attempting to retrieve API response via GET request using ngResource

I am trying to retrieve some data from an API using ngResource by utilizing the get method. Even though I have set up a factory for my resource, when implementing it in my controller, I encounter an error stating URL.split is not a function. I'm stru ...

Exploring AngularJS capabilities: iterating over a collection of objects generated by a method

My latest project involves retrieving data from an API using a controller. Here's the code snippet: .controller('MyDataController', ['$http', function($http) { pdc = this; pdc.projects = [] pdc.getData = function(val ...

What is the best way to auto-fill input fields with data from a Json file

My goal is to automatically populate HTML form fields based on user selection. I have obtained code for related functions, such as fetching JSON data and creating dropdown lists, from a friend. Here is the link to that code: https://jsfiddle.net/r4zuy7tn/1 ...

Animating sprites using TypeScript

I've been tackling the development of a small Mario game lately. However, I'm facing some difficulty when it comes to animating sprites. For instance, I have a mario.gif file featuring running Mario (although he's not actually running in th ...

How can we effectively translate intricate nested SQL relationships into manageable services using front-end data modeling best practices?

Seeking insights on potential solutions to a complex issue. Angular and Rails will be used, but this problem is more abstract and doesn't have to be addressed within these frameworks. What are the optimal methods for managing intricate nested SQL ass ...

Update input field value with data retrieved via ajax call in AngularJS

My current approach involves using AngularJS directives for Bootstrap in order to create an edit form on a Bootstrap modal when the user clicks on the edit button from a list of items. Here is the code I have implemented: HTML: <div class="modal-heade ...

Is there a way to simultaneously apply the :active pseudoclass to multiple elements?

<div id="a">A</div> <div id="b">B</div> <div id="c">C</div> <style> #a, #b, #c { height: 100px; width: 100px; background-color:red; font-size: 100px; margin-bottom: 20px; } ...

Exploring the power of tRPC for creating dynamic routes in NextJs

Recently, I embarked on a new project using the complete t3 stack (Nextjs, prisma, tailwind, tRPC), and encountered a minor hiccup. To provide some context, within my database, I have an "artists" table containing fields such as name, email, address, id, ...

Tips on saving Firebase Storage image url in Firebase database?

How do I store the URL of an image uploaded to Firebase Storage in Firebase Database? When executing the code below, I encounter the following error: Uncaught (in promise) FirebaseError: Function DocumentReference.set() called with invalid data. Unsuppor ...

Installing a package from a private repository using a different package name with npm

I'm looking to incorporate a module from a private GitHub repository into my project. To achieve this, I will execute the command npm install git+https://[API-KEY]:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0b737c6e607 ...

Passing state updates between child components by utilizing the useReducer hook and dispatching actions

Check out this interactive example on CodeSandbox with the code provided and highlighted linting issues: https://codesandbox.io/s/react-repl-bw2h1 Here is a simple demonstration of my current project setup. In a container component, there is an important ...

Using AngularJS directives like ng-hide, ng-show, or ng-if to control visibility based on the active state of

Hello, I am currently developing a shopping cart with three different views: menu, options, and order. The list is generated using ng-repeat from JSON data, with each item in the array having an 'active' field set to false. When an item is added ...

Transferring data files through an ajax-based form submission

I am encountering an issue when trying to send a file to a server using AJAX for submission. Despite attempting various methods involving var xhr = new XMLHttpRequest(); and $.ajax({});, I consistently receive the error message Uncaught TypeError: Illegal ...

When Utilizing an async Task Method, DbContext is Properly Disposed

Currently, I have set up an async Task method to handle the IAuthenticationFilter interface. After logging in successfully, I can access an API with no issues when it has this attribute. However, if I revisit the API later on, an exception is thrown. publ ...

When using NodeJS with expressJS, remember that req.body can only retrieve one variable at a

I'm having trouble with my login and signup pages. The login page is working correctly, but the signup page is only transferring the password for some reason. App.JS: var express = require("express"); var app = express(); var bodyParser = require("bo ...

Retrieve both the key and corresponding value from a JSON object

I am attempting to extract the key and value pairs from a JSON dataset. $.get(url, function (data) { console.log(data); if (data.Body != null) { console.log(data.Body); } }); These are my current logs: { $id: "1", Exceptions ...

Is there a way to dynamically insert page breaks in jspdf to ensure that tables do not split across multiple pages?

I am currently working on developing a website that can generate PDFs from database information, using PHP and MySQL to create tables with variable lengths. Sometimes, these tables may even span across multiple pages. If the first table takes up too much ...

Froala text area is unexpectedly visible when I attempt to cover it with a partially see-through mask

The website I'm currently developing features a semi-transparent overlay that dims the screen with a light-colored message displayed on top. This overlay and message are shown whenever there is a background process running. Everything was running smoo ...

How do I preserve data within $scope upon switching views using ng-include?

Can you please take a look at this jsFiddle? http://jsfiddle.net/mystikacid/b7hqcdfk/4/ This is the template code: <div ng-app="myApp"> <div ng-controller="dataCtrl"> <div>Data : {{data}} (Value outside views)</div> < ...

Changing the position of the icon in the bootstrap validator

I'm currently attempting to validate form fields in a web project. The goal is to achieve a specific result, similar to the image below: https://i.stack.imgur.com/EVeJf.png While I have made progress with a simple solution that almost meets the requi ...