0

i have a set of getJson() functions that I call consecutively using jquery deferred.

function f1(){ $.getJSON(..)}
function f2(){ $.getJSON(..)}
....
function fn(){ $.getJSON(..)}

var dfd = $.Deferred();
dfd.done(f1,f2...fn)

dfd.resolve();

The thing is, one of the function may encounter a given problem and return False, In this case I would like to stop the progress and not call the remaining functions.

How can I do that??

Mahmoud
  • 31
  • 3

1 Answers1

0

The two ways you can do this are

1. If the responses DO NOT depend on each other

var req1 = $.getJSON(...).then(function(response1) {
     //evaluate the response and either reject or resolve a Deferred based on the results of your evaluation
     if(!response1) { return $.Deferred().reject(); }
     return $.Deferred().resolve(response1);
});

var req2 = $.getJSON(...).then(function(response2) {
     //evaluate the response
     if(!response1) { return $.Deferred().reject(); }
     return $.Deferred().resolve(response2);
});

var req3 = $.getJSON(...).then(function(response3) {
     //evaluate the response
     if(!response1) { return $.Deferred().reject(); }
     return $.Deferred().resolve(response3);
});

var req4 = $.getJSON(...).then(function(response4) {
     //evaluate the response
     if(!response1) { return $.Deferred().reject(); }
     return $.Deferred().resolve(response4);
});

$.when(req1,req2,req3,req4)
  .then(
    function(response1,response2,response3,response4) { /* called when all requests are successfully complete */ },
    function() { /* called when any of the requests have failed */ }
   );

2. If the responses DO depend on each other

$.getJSON(...) //req1

 .then(function(response1) {

    //evaluate response1
   if(!response1) { return $.Deferred().reject(); }
   return $.Deferred().resolve(response1);

 })
 .then(function(response1) {

   return $.getJSON(...).then(function(response2) {
     //evaluate the response
     if(!response2) { return $.Deferred().reject(); }
     return $.Deferred().resolve(response1,response2);
   });

 })
 .then(function(response1,response2) {

   return $.getJSON(...).then(function(response3) {
     //evaluate the response
     if(!response2) { return $.Deferred().reject(); }
     return $.Deferred().resolve(response1,response2,response3);
   });

 })
 .then(function(response1,response2,response3) {

   return $.getJSON(...).then(function(response4) {
     //evaluate the response
     if(!response4) { return $.Deferred().reject(); }
     return $.Deferred().resolve(response1,response2,response3,response4);
   });

 })
 .then(

   function(response1,response2,response3,response4) {
     //only called on success of all requests
  },

  function() {
    //called on failure of any individual request, or if the responses of any individual request did not meet your conditions
  }
)

EDIT

If you are performing these in a function, then you simply need to return the promise and chain it to a .then like such:

function makeReqs() {
  //method 1
  return $.when(req1,req2,req3,req4);

  //method 2
  return $.getJSON(...)
      .then(...)
      .then(...)
      .then(...)


}

//call the function
makeReqs
  .then(
    function() { /* this is called on success */ },
    function() { /* this is called on failure */ }
   )
Adam Jenkins
  • 51,445
  • 11
  • 72
  • 100
  • .pipe has been deprecated as of jQuery 1.8 – peinearydevelopment Apr 02 '15 at 18:05
  • @peinearydevelopment - thanks, I've been working with old versions lately. Should be using `$.then` I'll edit. – Adam Jenkins Apr 02 '15 at 18:06
  • Thank you but how do I trigger the success or the failure function? – Mahmoud Apr 02 '15 at 18:06
  • the thing is that I want to abandon the execution depending on the return value of one of the getJsons – Mahmoud Apr 02 '15 at 18:10
  • @MahmoudKsemtini - the answer has been edited. All you need to do is return either a `resolved` or `rejected` promise based on the response inside a `.then` method chained to the `$.getJSON` request. – Adam Jenkins Apr 02 '15 at 18:23
  • To keep a promise chain on the success path, you don't need to return a new Deferred - simply return data. Thens in this answer will simplify to `return response || $.Deferred().reject('reason')`. Also `$.when.apply()` is only necessary when you pass an array of promises - for a standard parameter list, it's just `$.when(req1,req2,req3,req4)`. – Roamer-1888 Apr 02 '15 at 23:11
  • @Roamer-1888 - both correct points. I will edit this answer. If you want to pass multiple parameters to a `.then`, however, you need to return a resolved deferred with multiple arguments via `$.Deferred().resolve(arg1,arg2).then(function(arg1,arg2) { });` – Adam Jenkins Apr 02 '15 at 23:48
  • Yes indeed. That alone is probably reason enough not to propagate previous results that way. Answers [here](http://stackoverflow.com/questions/28250680/) cover just about all aspects of the topic. – Roamer-1888 Apr 03 '15 at 00:20