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

I'm trying to use Route.get() but it seems I forgot to include a callback function. What mistake did I make?

I've searched through various answers on different platforms, but I'm still struggling to understand. What mistake have I made? Can someone provide assistance? *revised. I have included requiring routes and app.use. It seems like the function is ...

Issue with Bootstrap jQuery dynamic table edit/delete/view button functionality not functioning as expected

Could really use some assistance with this issue. I have a DataTable that includes a button in the last column which offers options like Edit/Delete/View. When clicked, it should delete the entire row. However, I'm struggling to access the current ele ...

PHP - Extract Information from Table Upon Form Submission without User Input

I'm facing a challenge with my web form that includes a table allowing users to delete rows before submitting. Although there are no input fields in the table, I need to capture the data from these rows when the form is submitted. The issue is that th ...

Disabling row checkboxes in Datatables jQuery depending on cell value: a comprehensive guide

Is there a way to disable row checkboxes based on the cell value in Datatables? My table has several columns with data like "System". If the cell value is "System", I want to disable the row's checkbox. I've tried the code below, but the checkbox ...

Configuring IIS Rewrite can be easily achieved by following these simple

My project utilizes PHP and Angular, hosted on IIS. I have enabled the html5Mode in Angular, allowing me to use routes like localhost/home instead of locahost/#/home. The issue arises when I copy and paste the URL (for example: http://localhost/home) into ...

What is the best way to remove an active item from a Vue v-list?

When using Vuetify's v-list-item directive, I encountered an issue where the active prop cannot be removed once an item has been selected. Here is my approach so far: <v-list-item-group pb-6 color="primary" class="pb-3 text-left"> ...

Encountering a 404 error in an AngularJS app within Cordova on Android

Currently, I am working on an android application using Cordova and AngularJS (front-end framework OnsenUI). Below is the code snippet for my GET request to retrieve data from the server: $http.get(url+"getlotterylist").then(function(msg){ $scope. ...

The output of new Date() varies between app.js and ejs

app.get("/test",function(req,res){ var d = new Date(); res.send(d); }); When I access mydomain/test, it displays the output "2019-03-19T04:50:47.710Z" which is in UTC. app.get("/testejs",function(req,res){ res.render("testejs");}); Below is the content ...

The issue arises in Selenium IDE when a variable is mistakenly identified as a string instead of a

Hey there, I've encountered an issue while using Selenium IDE. I'm trying to increment a variable by two, but instead of performing numerical addition, it seems to be concatenating strings. <tr> <td>store</td> <td> ...

Every time I try to request something on my localhost, NextJS console throws a TypeError, saying it cannot read the properties of undefined, specifically '_owner'

Update: I've noticed that these errors only appear in Chrome, while other browsers do not show them. Recently, I created a simple NextJS project by following a couple of tutorials, which also includes TypeScript. However, after running npm run dev, I ...

Service in AngularJS with multiple functions

I seem to be encountering an issue with the service in my AngularJS application. I am receiving the following error: Uncaught SyntaxError: Unexpected identifier Error: [$injector:unpr] Unknown provider: NewContactDataProvider <- NewContactData This is ...

Reveal or Conceal Information Depending on Cookie Status

Below is the Jquery code I am using: $("#tool").click(function() { $(".chelp").slideToggle(); $("wrapper").animate({ opacity: 1.0 },200).slideToggle(200, function() { $("#tool img").toggle(); }); }); When the #tool img is clicked, bot ...

Clicking on the ng-repeat will trigger the ng-click event, which populates all the data using ng

I need help including an HTML page using ng-click within ng-repeat. However, it is currently loading all the content for every ng-repeat element. My specific requirement is to only bind(ng-include) the clicked element. Please see the attachment for m ...

Experiencing the 'Rich Embed fields cannot be empty' error even though my code is functioning properly

My code is set up to log when someone edits a message on Discord. It captures the original message, the edited message, the channel, and more details. Everything seems to be working fine, but I keep encountering an error indicating that my RichEmbed fields ...

What is the procedure for eliminating an event listener that does not directly invoke a function?

I have implemented an event listener in my JS file following a successful AJAX request: var pageButtonsParentElement = document.getElementById("page-buttons"); pageButtonsParentElement.addEventListener('click', event => { ...

What is the best way to access an external array using ng-repeat in AngularJS?

My dataset consists of 3 separate arrays. "areas": { "default": [ { "area": "Master Bedroom", "uuid": "986e3f42-1797-49ae-b060-181a33b9", "description": "", "new": [ { "value": "986e3f42-1797-49ae-b060-181a3 ...

steps to initiate re-render of rating module

My first experience with React has been interesting. I decided to challenge myself by creating a 5-star rating component. All logs are showing up properly, but there seems to be an issue with the component not re-rendering when the state changes. Thank you ...

Have Vue props been set to null?

Currently, I have a component within my vue.js application that looks like this: export default { props: ['forums'], methods: { increment(forum, index) { ForumService.increment(forum) .then(() => { ...

Avoid having individual words centered on a single line of text

Currently, I'm in the process of developing a website using WooCommerce, WordPress, and Elementor. I've encountered an issue where only one word appears on each line and have tried various solutions such as hyphens, word-break, and line-break wit ...

The dropdown menu in AngularJS is unable to retrieve the selected index

Presently, I have a dropdown menu: <select class="form-control" name="timeSlot" ng-model="user.dateTimeSlot" ng-change="dateTimeChanged(user.dateTimeSlot)" ng-blur="blur29=true" required style="float: none; margin: 0 auto;"> ...