6

Can someone explain why in the following example, foo() is returning the whole promise instead of just the data ? And how to make foo() return only the data ?

var foo = function() {
  var promise = $.ajax({
    type: 'POST',
    url: 'http://example.com'
  })

  return promise.done(function(data) {
    return data
  })
}

console.log(foo())

Thanks!

inwpitrust
  • 561
  • 3
  • 7
  • 20

1 Answers1

6

Done always returns the promise, it does not make sense to return anything from the function that you supply to done:

The deferred.done() method accepts one or more arguments, all of which can be either a single function or an array of functions. When the Deferred is resolved, the doneCallbacks are called. Callbacks are executed in the order they were added. Since deferred.done() returns the deferred object, other methods of the deferred object can be chained to this one, including additional .done() methods Source: https://api.jquery.com/deferred.done/

promise.done(...).done(...) or promise.done(fn1, fn2) are equivalent.

You can use .then if you want to return a new promise with a new value for "data", i.e.:

promise.then(function(data1){
  return data1.result;
}).done(function(data2){
  //the value of data2 here will be data1.result 
});

A somewhat common use of then is to return a new promise, for example:

promise.then(function(data){
  return $.ajax(...);
}).done(function(resultFromAjaxCall){});
Rui
  • 4,847
  • 3
  • 29
  • 35
  • 1
    Yes, I get that, but I still don't understand why "it does not make sense to return anything from the function that you supply to done"? See my response to BenjaminGruenbaum, what if I need to manipulate the data outside the promise "context"? – inwpitrust Mar 28 '14 at 11:06
  • @inwpitrust It does not make sense simply because that value is not used (it is used in .then though). Also, you can update a variable outside of the scope of the promise's "context", making the data available outside the scope of the function that you pass to done. – Rui Mar 28 '14 at 11:31
  • "you can update a variable outside of the scope ..." that you can't do, the variable will always be undefined, see [this question's example](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call) – inwpitrust Mar 28 '14 at 12:14
  • @inwpitrust It will be updated when the callback runs, if you check it immediately before it will be undefined or have the value it had previously. The behavior you're describing is to treat an async call as if it were synchronous. – Rui Mar 30 '14 at 12:01