AngularJs - A directive for handling asynchronous operations with deferred or batched processing

I've exhausted my efforts searching through Google and books for a solution, so unfortunately I don't have any code to provide at the moment.

My objective is the following:

1 - Develop a directive that accepts 2 parameters in this format

<resource resource-area="AREA" resource-key="KEY" />

2 - Rather than immediately altering the output during compilation, store the requested "resource" directives (or their related objects like element or attrs) in a temporary "batch" within the $scope.

3 - Once the compile process for the view containing the directives has finished (or is almost complete), then proceed with compiling all of the directives.

The goal here is to only make a single ajax call for all directives instead of one call per directive.

I hope this explanation makes sense. Despite thorough research and examination of documentation and search results, I haven't found a definitive solution yet. It's possible there isn't one, but I remain optimistic :)

Answer №1

UPDATE: Modified approach following the creation of proof-of-concept code below.

Have you considered switching to using a service instead of an http interceptor and?

  1. Directives are compiled and linked
  2. They initiate http requests using promises for the results
  3. The http requests are intercepted and saved in a service
  4. Once all directives have completed their tasks, instruct the service to initiate your batch request The service initiates the requests at a predetermined time interval.

The revised approach eliminates the need for an http interceptor due to complications with circular dependencies during testing.

You can see the revised solution in action at http://plnkr.co/edit/eCb3wm

To begin, create a service to store all requests and execute them later:

app.service('HttpBatch', function($q, $http, $interval) {
  var batch = [];

  // Executes contents of the batch
  // Removes item from batch after execution
  var fireBatch = function() {
    while (batch.length > 0) {
      var batchObj = batch.shift();
      console.log('Executing batchObj: ', batchObj.config);
      // Execute the request and resolve its promise
      // with the result of the http promise
      batchObj.deferred.resolve($http(batchObj.config));
    }
  };

  // Adds a request object to the list
  // Returns a promise for the passed request
  var addRequest = function(reqConfig) {
    var deferred = $q.defer();
    batch.push({
      config: reqConfig,
      deferred: deferred
    });
    return deferred.promise;
  };

  // Executes every 3 seconds
  // Adjust the interval as needed
  $interval(fireBatch, 3000);

  return addRequest;
});

Next, incorporate the service into your directives instead of using $http.
As an example, here's a directive that utilizes the batch service for its requests.

app.directive('fireReq', function(HttpBatch) {
  return {
    scope: {},
    link: function(scope, el, attrs) {
      var me = 'Directive ' + attrs['fireReq'];
      console.log(me);
      // Example url only
      // Provide a config object similar to when using $http
      // Returns a promise
      HttpBatch({
        method:'GET',
        url:'http://run.plnkr.co/user/' + attrs['fireReq']
      }).then(function onSuccess (res) {
        console.log(me + ' received successful response: ', res);
      }, function onFailure (res) {
        console.log(me + ' encountered failure response: ', res);
      });
    }
  };
});

This solution heavily relies on $q and promises, so familiarize yourself with them before diving into how the above code functions.

Furthermore, it's essential to conduct thorough testing on the code before deploying it in a production environment.

Hopefully, this aids you in your specific situation. It was certainly a valuable learning experience for me as well :)

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

Tips on incorporating an item into an array solely when a specific condition is met

Consider the following arrow function that creates an array: const myFunction = () => ["a", "b", "c"]; I am looking to modify this function to add another element if a specific argument is true. For example, I want it to look like this: const myFunc ...

Steps to bring life to your JavaScript counter animation

I need to slow down the counting of values in JavaScript from 0 to 100, so that it takes 3 seconds instead of happening instantly. Can anyone help me with this? <span><span id="counter"> </span> of 100 files</span> <s ...

How does Angular handle the output from a parser and formatter function?

I'm feeling quite baffled about what should be returned in a parser function and a formatter function on an ngModel controller. I understand that when a value is invalid, you return undefined in the parser function, otherwise you return the valid val ...

What steps should I take to include a Follow - Unfollow Button on my Website?

I need to add a button on my website that allows users to either follow or unfollow a specific game. Here is the table for the follow buttons: Follow Button Table When a user clicks on the button related to the game ID, it should update the game_follow d ...

What is the best way to include a JavaScript function within a JSON file?

I am attempting to transform a JSON file into an object within my application, complete with embedded functions. However, I am facing difficulties in accomplishing this task. The JSON file causing issues is as follows: { "draw": function() { ctx.cle ...

Utilizing Projector and Ray in three.js to target and select a vertex

I am working on a project where I need to load an .obj file representing a human body. The goal is to allow users to select two vertices and highlight them with flags, followed by finding the index of these vertices in the original .obj file. Subsequently, ...

Verifying the accessibility of a website using JQuery/Javascript

I am attempting to use JavaScript to ping a website and display the result. Unfortunately, I have not had any success with this JSFiddle: https://jsfiddle.net/yyjowtru/ Although I believe I am close to achieving the desired outcome, changing the URL in t ...

embed a hyperlink onto a live video at a designated moment within an HTML document

Can anyone help me figure out how to overlay a link over a video playing at a specific time on an HTML page? I know it's easy to do on Youtube, but I need to accomplish this task without using Youtube. :) Thank you in advance for any assistance! ...

Leveraging the array for fetching JSON data

I'm currently utilizing this code snippet to parse json data: $.getJSON(geocodingAPI, function (json) { // Extracting variables from the results array var address = json.results[0].formatted_address; console.log('Address : ', a ...

React: Using Chart.js to visualize negative values with a different color in the area

I am implementing a line chart using Chart.js and react-chartjs-2 to display positive and negative values. For positive values, I want the filled area to be green, and for negative values, I want it to be red. Check out the code here import React from &qu ...

Avoid including package-lock.json file in GitHub contribution history

After the release of npm v5.0.0, utilizing npm packages automatically generates a package-lock.json file when running npm install. In my situation, my package-lock.json document is almost 10,000 lines long. Npm advises that this file should be committed: ...

What is the best way to display a message on the 403 client side when an email sending fails?

I am attempting to display an alert message when the email is sent successfully or if it fails. If it fails, I receive a 403 status code from the backend. However, I am unsure how to handle this error on the client-side. In the case of success, I receive a ...

Encountering difficulties loading Google Maps with jQuery

When attempting to load a map on my page, I encountered a problem when including the jquery.min.js file in the head tag. If it is included, I receive an initMap : no such method error. However, if I reverse the order of inclusion, with maps first and then ...

navigating a pointer graphic within a container

I've been working on creating a sniper game, but I've run into an issue with moving the sniper image inside the div. My main objective is to change the image to the sniper image when the mouse hovers over the div. Here's what I have tried so ...

Angular unable to register service worker

Looking to implement push notifications in my Angular app using vanilla JavaScript instead of the Angular service worker or @angular/pwa. In angular.json, I've specified the path to the js file under the script option. However, when the service worke ...

Deactivate the AJAX button after the specified number of clicks

Imagine I have a model called Post, and it can be associated with up to n Comments (where the number is determined by the backend). Now, let's say I have a view that allows users to add a Comment through an AJAX request. What would be the most effecti ...

Difficulty recognizing sessions in production for a self-hosted Next.js application using Clerk Dev Auth

Having trouble finding the next step in debugging as I couldn't resolve the issue on Clerk's Discord or GH Issues. It seems like it might be a Next.js problem rather than a Clerk one? I am currently running a self-hosted next.js app in a docker ...

What is the best way to navigate a carousel containing images or divs using arrow keys while maintaining focus?

Recently, I have been exploring the Ant Carousel component which can be found at https://ant.design/components/carousel/. The Carousel is enclosed within a Modal and contains multiple child div elements. Initially, the arrow keys for navigation do not work ...

Encountered a 'Require() of ES Module' Error while Implementing Visx with Nextjs

Currently, I am utilizing the Visx library for chart creation within Nextjs. The scales provided by Visx are imported in this manner: import { scaleBand, scaleLinear, scaleOrdinal } from "@visx/scale" It is important to note that internally, Vi ...

Avoid nesting a VirtualizedList component inside a basic ScrollView in React Native to prevent issues

I have come across this question multiple times, and I've gone through all the suggested solutions. Most advise against nesting it inside ScrollView and recommend using SafeAreaView or another alternative instead. However, my scenario is a bit differe ...