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?
- Directives are compiled and linked
- They initiate http requests using promises for the results
- The http requests are
intercepted and saved in a service
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 :)