Creating a custom service that utilizes $cacheFactory

Utilizing $cacheFactory to store configurations and user data for one-time retrieval:

var cache = $cacheFactory("Temp");

    var getCachedData = function (url) {

        var data = cache.get(url);

        var deferred = $q.defer();

        if (data) {
            deferred.resolve(data);
        } else {
            readFromServer(url).then(function(result) {
                cache.put(url, result);
                deferred.resolve(result);
            });
        }
        return deferred.promise;
    };

    return {
        GetCachedData: getCachedData
    };

If the service receives null data, it will make a call to the server. Otherwise, it will retrieve the data from the cache. If a second call is made before the first completes, how can we implement a lock mechanism similar to C# in JavaScript?

Answer №1

To prevent multiple calls to the same API, consider implementing a solution like the following (not tested but should function properly):

var isDataRetrieving = false;
var deferredQueue = [];

var fetchData = function(url) {
    var data = cache.get(url);

    var deferred = $q.defer();

    if (data) {
        deferred.resolve(data);
    } else if (isDataRetrieving) {
        deferredQueue.push(deferred);
    } else {
        isDataRetrieving = true;
        deferredQueue.push(deferred);

        fetchDataFromServer(url).then(function(result) {
            cache.put(url, result);
            
            for(var i = 0; i < deferredQueue.length; i++) {
                deferredQueue[i].resolve(result);
            }
        });
    }
    return deferred.promise;
};

Here's how it operates:

  • If the data is already in the cache, immediately return it by resolving the deferred
  • If the data is not cached and isDataRetrieving is false, initiate the request and set isDataRetrieving to true
  • If the data is not cached and isDataRetrieving is true, indicating another call is ongoing, add the deferred to an array without taking any action

After the single call completes, resolve each deferred stored in the deferredQueue array to deliver the data to every caller.

Does this approach meet your requirements?

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

Pulling down the data with Ajax "GET"

When a user clicks on a button, a zip file will be downloaded. I have the necessary components in place, but I am struggling to ensure they work together seamlessly. The "GET" call will retrieve byte content with the content type specified as application/ ...

Automatically adjusting the locale settings upon importing the data

Is there a way to create a dropdown menu of languages where clicking on one language will change the date format on the page to match that country's format? In my React app, I am using moment.js to achieve this. My plan is to call moment.locale( lang ...

Executing a series of AJAX requests within a loop

I am looking for a way to optimize sending multiple AJAX calls simultaneously in Javascript/Angular. Despite my efforts to find a solution, I have come up empty-handed. My goal is to send all requests as quickly as possible without waiting for each one to ...

Guide on Linking a Variable to $scope in Angular 2

Struggling to find up-to-date Angular 2 syntax is a challenge. So, how can we properly connect variables (whether simple or objects) in Angular now that the concept of controller $scope has evolved? import {Component} from '@angular/core' @Comp ...

Uncovering the secrets of accessing req.body through expressjs

I'm having trouble accessing the body when receiving an expressjs request Here is my main server.js file: app.use(express.urlencoded({extended: true})); app.use(express.json()); app.use(router); And this is my router.js file: ...

What are the steps for updating an NPM package that was installed from a Git repository?

I'm struggling to understand how to update a package that was installed from a git repository. Let's say I have a package located at git+ssh://<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d4b3bda094b3bda0b8b5b6fab1 ...

Restrict access to PHP scripts to only be allowed through AJAX requests

Within my content management system (CMS), I have a specific page that fetches various mini-interfaces from PHP files located in an /ajax directory using AJAX. I am wondering if there is a way to restrict access to these files solely through AJAX requests ...

The useEffect function is failing to execute when deploying on Vercel with Vite and React Router

After successfully deploying a React site using Vite on Vercel, with React Router for routing and a separate backend service, everything seemed to be working fine on my local machine. However, when testing the deployment on Vercel, I encountered an issue w ...

ESLint warning: Potentially risky assignment of an undetermined data type and hazardous invocation of an undetermined data type value

Review this test code: import { isHtmlLinkDescriptor } from '@remix-run/react/links' import invariant from 'tiny-invariant' import { links } from '~/root' it('should return a rel=stylesheet', () => { const resp ...

How to access a grandchild's property using a string in JavaScript

Is there a way to access a property nested deep within an object when creating a custom sorting function? I am attempting to implement a sort function that can sort an array based on a specific criteria. const data = [ { a: { b: { c: 2 } ...

Modify the text inside a div based on the navigation of another div

Hey there, experts! I must confess that I am an absolute beginner when it comes to JavaScript, JQuery, AJAX, and all the technical jargon. Despite my best efforts, I'm struggling to grasp the information I've found so far. What I really need is ...

Creating a personalized ESLint rule specifically for Redux reducers

Currently working with Redux and Redux Toolkit alongside ESLint presents a challenge. Sometimes, when adding my extraReducers, I find that I do not need both the state and action properties provided by Redux. As a result, ESLint throws an error in these c ...

Is there an HTML code block available for embedding an HTML snippet?

This has got to be one of the most irritating things I've encountered haha. So, I'm using prettify.js to add syntax coloring to my code, but whenever I try to encode HTML using either prettify.js or prism.js, I have to format it like this with a ...

What is the best way to define a variable in EJS?

I need to populate my database array results on the frontend using EJS. The code snippet I'm using is as follows: var tags = ["<%tags%>"] <% for(var i=0; i<tags.length; i++) { %> <a href='<%= tags[i] %&g ...

Steps for executing the function in the specifications - Protractor

My script is written within the following module: var customSearch = function () { this.clickSearch = function (value) { element(by.id('searchbutton')).click(); }; this.waitElementFound = function (value) { var EC = protractor.Ex ...

The absence of localStorage is causing an error: ReferenceError - localStorage is not defined within the Utils directory in nextjs

I've been trying to encrypt my localstorage data, and although it successfully encrypts, I'm encountering an error. Here's the code snippet (./src/utils/secureLocalStorage.js): import SecureStorage from 'secure-web-storage' import ...

Is there a way to make the image above change when I hover over the thumbnail?

Seeking assistance with JavaScript to enable changing thumbnails on hover. As a newcomer to JavaScript, I'm struggling to grasp how to achieve this effect. I've already implemented fancybox for gallery functionality. Below is the HTML and CSS f ...

Struggling to retrieve user input from a textfield using React framework

I'm having trouble retrieving input from a text-field in react and I can't figure out why. I've tried several solutions but none of them seem to be working. I even attempted to follow the instructions on https://reactjs.org/docs/refs-and-th ...

Tips on keeping a floating sidebar afloat as ajax content loads

I'm quite the beginner in JavaScript, so here's my question. I have a floating sidebar that stops floating when it reaches the footer. Here is the JavaScript code: $(window).load(function(){ $(function() { var top = $('#sidebar ...

Customizing vertex sizes in BufferGeometry for diverse shapes

Currently, I am working on creating a 2D scatterplot using three.js and I need to customize the sizes of the points. You can check out my progress here. I'm struggling with adjusting the sizes of the points based on the "radius" property and also addi ...