1

I would like to apply a condition to each deferred request within a $.when() function (before the request is made). However placing an if condition inside $.when returns an error.

What would be the proper way to do what I essentially describe bellow?

$.when(
  if(var1) {
    $.getJSON(url1, function(data) {...}),
  },
  if(var2) {
    $.getJSON(url2, function(data) {...}),
  },
  if(varN) {
    $.getJSON(urlN, function(data) {...}),
  },
).then(function() {
  ...
});
Sebastien
  • 2,607
  • 9
  • 30
  • 40
  • Just construct a variable length array of promises based on your conditionals and then do `$.when.apply($, array).then(...)` – jfriend00 May 14 '17 at 20:52

2 Answers2

7

You can simply construct an array of AJAX promises instead. After that, use $.when.apply($, <yourArray>). To illustrate the solution, here is an example based on the code you have provided:

// Construct array to store requests
var requests = [];

// Conditionally push your deferred objets into the array
if(var1) requests.push($.getJSON(url1, function(data) {...}));
if(var2) requests.push($.getJSON(url2, function(data) {...}));
if(var3) requests.push($.getJSON(url3, function(data) {...}));

// Apply array to $.when()
$.when.apply($, requests).then(function() {
  // Things to do when all is done
});

What that in mind, here is a code snippet that shows a proof-of-concept example: I am using dummy JSON returned by JSONPlaceholder:

$(function() {
  // Construct array to store requests
  var requests = [];
  
  // Conditional vars
  var var1 = true,
      var2 = false,
      var3 = true;

  // Conditionally push your deferred objets into the array
  if (var1) requests.push($.get('https://jsonplaceholder.typicode.com/posts/1', function(data) {  return data;
  }));
  if (var2) requests.push($.get('https://jsonplaceholder.typicode.com/posts/2', function(data) {  return data;
  }));
  if (var3) requests.push($.get('https://jsonplaceholder.typicode.com/posts/3', function(data) {  return data;
  }));

  // Apply array to $.when()
  $.when.apply($, requests).then(function(d) {
  
    // Log returned data
    var objects = arguments;
    console.log(objects);
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Terry
  • 63,248
  • 15
  • 96
  • 118
-3

You can use ternary operator in $when(). The below code worked for me:

var includeX = true, includeY = false;
var x = $.get('check.html');
var y = $('div').animate({height: '200px'}, 3000).promise(); // you may use an ajax request also here
$.when(includeX ? x : '',  includeY ? y: '').done(function(){
    console.log(x);
    console.log(y);
    console.log('done');
})
  • In principle, yes, however `.animate()` returns jQuery, not promise. Try `var y = $('div').animate({height: '200px'}, 3000).promise();` – Roamer-1888 May 14 '17 at 20:49
  • Agreed. However, animate() was used just to induce a delay and check the code with promise and when. Ajax request will also hold good with the above code. – Rajalakshmi P May 14 '17 at 21:17