0

I am wondering what would be the best way to implement a function, that would be responsible for toggling a gif on certain requests. I don't want to display it on all of the http requests, so I don't want to place it within the interceptor - I want to create a service.

I was most likely going to go with a function that will work as following:

LoaderFunction(SomeFunction())

Which will toggle a img or whatever whenever the promise is initiated and resolved. The SomeFunction() will usually be http requests, which already have their own promise.

Thanks!

uksz
  • 18,239
  • 30
  • 94
  • 161

2 Answers2

1

The easiest way would be to use a counting semaphore and the disposer pattern. It would work for any number of ongoing requests.

withLoader.count = 0;
function withLoader(fn){
     if(count === 0) initiateLoader();
     count++;
     return $q.when(fn).finally(function(){
         count--;
         if(count === 0) finishLoader();
     });
}

This binds a scope to the lifetime of an event - like RAII in C++. This'd let you do:

withLoader(someFunction);
withLoader(someFunction);
withLoader(function(){
    return $http.post(...); 
}).then(function(){
   // http request finished, like your normal `then` callback
});

The loader would finish when the counter reaches 0, that is when all requests finish.

Since it's Angular, you probably want to put withLoader in its own service and have a directive manage the loading itself.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
0

Well, the easiest way to do it is through the use of promises on the $http calls themselves.

Example:

$http.post("/", data, function() {
  initiateLoader(); // this is a function that starts the loading animation.
}).success(function (data) {
  finishLoader(); // this is a function that ends the loading animation.
}).catch(function(err) {
  finishLoader(); //so the loader also finishes on errors.
});
Nick Snick
  • 911
  • 1
  • 9
  • 16
  • I think this is not the best way to implement this - imagine what would happen if you would have many requests at the same time - they would get into a conflict, and toggle themselves on and off even though some requests are not finished. – uksz Dec 10 '15 at 07:46
  • Good point for sure, one way to fix that would be to give an ID to the loaders & pass that into the function, instead of using the same loader for all the different requests. – Nick Snick Dec 10 '15 at 07:49
  • Instead of using a combination of `.success` and .`catch` you could use jquery's `.always` – kernel Mar 21 '18 at 10:20