0

Is this a bad way to do this? I'm basically chaining promises, where each successful return from server, launches a new http.get() for more information BUT NOT when it errors. No more http.get()s if it causes an errorCallback!

$http.get(...).then(function() {
  $http.get(...).then(function(){ 
      $http.get(...).then(function(){}, function(){}), 
   function(){}); }, 
mainErrorCallback);

Would it make a difference if it was instead of "$http.get()" it does "ViewsService.loadViews()" inside the

$http.get(...).then( function() { ViewsService.loadViews(); }, function(){ console.log("error"); }). 

EDIT: Here's what I mean, synchronously.. it seems like it works, but code needs cleanup/efficency to look a little neater:

http://jsfiddle.net/4n9fao9q/6/

(with delayed http requests): http://jsfiddle.net/4n9fao9q/26

Dexter
  • 6,170
  • 18
  • 74
  • 101
  • Is there any dependency between the resulting promise and the calling promise which is inside the then block.? – Kalyan May 16 '17 at 21:01
  • Yes so the whole point is to chain... ONE succeeds, then DO NEXT http.get... SECOND succeeds ONLY THEN, do THIRD. And yes it should WAIT for the responses from server. But my jsfiddle example shows that it does wait... http://jsfiddle.net/4n9fao9q/2/ – Dexter May 17 '17 at 00:18
  • User the $q service. It allows for: $q.all([array of promises]).then() – makeitmorehuman May 17 '17 at 13:22

2 Answers2

2
$http.get(...).then((res) => {
  //res has data from first http
  return $http.get(...);
}).then((res) => {
  //res has data from second http
  return $http.get(...);
}).then((res) => {
  //res has data from third http
}).catch((err) => {
  //exploded
});

I think is cleaner. You can replace $http.get with whatever function returns a promise. If ViewsService.loadViews() returns a promise, you can use it.

As asked in the comments.

...
ViewsService.loadViews = function() {
  //returns a promise
  return $http.get(...);
}

OR

ViewsService.loadViews = function() {
  return new Promise((resolve, reject) => {
    $http.get(...).then((result) => {
      //whatever
      return resolve();
    })
  })
  return $http.get(...);
}

With any of this options for loadViews you can do ViewsService.loadViers.then(etc)

yBrodsky
  • 4,981
  • 3
  • 20
  • 31
  • But what if, ViewsService.loadViews has its own http.get... but no promise. Does that break the lifecycle? Does that mean the http.get inside "loadviews" which is called inside .success( ) { } is asynchronous with the http.get first fired? – Dexter May 17 '17 at 00:22
  • Yes I think your code is correct. http://jsfiddle.net/4n9fao9q/10/ It does seem to chain it. – Dexter May 17 '17 at 00:40
  • One final question, i wanna be sure that if the first request takes too long, that it doesn't fire off the subsequent calls in ".then" is this why you "return" the $http.get instead of just "calling the $http.get"? – Dexter May 17 '17 at 00:51
  • Comparing http://jsfiddle.net/4n9fao9q/27/ and http://jsfiddle.net/4n9fao9q/26/ (return vs not return) – Dexter May 17 '17 at 01:13
  • Subsequent requests will be called after the first one finishes with this configuration. – yBrodsky May 17 '17 at 12:34
  • If ViewsService.loadViews has it's own http.get you can return it. Check my edit – yBrodsky May 17 '17 at 12:35
  • ok I get it now. So your edited code where you return the promise from loadViews is only important if the code above needs the output from it. I just need it chained, the outputs are collected elsewhere when the final http.get is transmitted and succeeded. – Dexter May 17 '17 at 15:45
1

Is this a bad way to do this?

  • Efficiency

Unless you are using the response from the first request as input to the following request then this isn't a very efficient way to do this, as each request will be blocked until the previous one has returned. A better way would be to use $.all($http.get(...),$http.get(...))

  • Style

The nested calls (the pyramid of doom) are difficult to read. As each call has the same failure response you could just chain these calls instead. e.g.

$http.get(..).then
($http.get(..)).then(
($http.get(..)).catch(errHander)
user1438038
  • 5,821
  • 6
  • 60
  • 94
aengus
  • 605
  • 6
  • 13
  • Interesting... No I don't want asynchronous. I want synchronous (I don't want all firing at once, I want the user to wait because I want everything loaded in order). Do #1, wait for response, only do #2 if #1 succeeded, then fire #3 request, then wait for #3 request, if succeeds, only THEN do #4. – Dexter May 17 '17 at 00:20