0

I am trying to wrap a jQuery AJAX request in a Ember RSVP promise, and I have this issue where the value I send to the resolve function (which is the jqXHR parameter) changes from object to string.

The code for doing the request + creating the request is as follows:

return new Ember.RSVP.Promise(function(resolve, reject) {
  Ember.$.ajax([URL], {
    type: 'POST',
    dataType: 'text'
  }).then((data, textStatus, jqXHR) => {
    console.log(jqXHR);
    resolve(jqXHR);
  }, (jqXHR, textStatus, errorThrown) => {
    resolve(jqXHR);
  });
});

And in my controller, I handle the request like this:

promise.then((response) => {
  console.log(response);
  if (response.status === 200) {
    something...
  } else {
    something else...
  }
  receipt.set('busy', false);
});

Now, from the basic (and probably flawed) comprehension I have of RSVP.Promise, the resolve(jqXHR) line should send the jqXHR object as parameter to the callback, right?

Problem is, when I print the response I get in the console, all I get is 200 success, which is the body of the HTTP request I do.

However, when I print the jqXHR before resolving it, it correctly prints the whole object:

Object {readyState: 4, responseText: "200 success", status: 200, statusText: "OK"}

So why is this happening? Is Ember doing some wierd black magic and converts the jqXHR object to string? Or is the data string being sent in lieu of the jqXHR object I am expecting?

Thanks!

blue
  • 125
  • 10
  • You know you can do `Ember.RSVP.resolve($.ajax(...)).then(...)`? – Lux Oct 03 '16 at 13:31
  • 1
    In `resolve(jqXHR)` try sending data and status too like this `resolve(data,jqXHR.status)` – Ember Freak Oct 03 '16 at 13:37
  • @Lux Yes, but the jQuery `ajax` method takes two callbacks, and the `jqXHR` comes first in the `done` callback and third in the `fail` callback, so I am trying to re-arrange the parameters a little bit before resolving my promise. – blue Oct 03 '16 at 13:40
  • @kumkanillam Thanks, it works! But I still can't figure out why the `jqXHR` is converted to string when passed to the promise. Is this normal? – blue Oct 03 '16 at 13:42
  • 1
    Don't know about this conversion, may be need to check with source code. – Ember Freak Oct 03 '16 at 14:01
  • 1
    @kumkanillam Checked what was up in the source code, and I found the answer to my issue. I will post it here as an answer, it that interests you. Thanks for your help! – blue Oct 03 '16 at 15:31

1 Answers1

1

Got it!

Alright, so apparently rsvp.js checks if the object sent to the resolve method is 'thenable' (read then-able), i.e. if it contains a then method.

If it is 'thenable', it will execute the then method of the object, take its first argument (only) and take it as the fulfilled value. This little magic allows chaining resolves but doesn't work very well with callbacks that take multiple arguments.

So in my case, I was sending jqXHR to be resolved, which does contain a then method (according to the jQuery documentation). RSVP then tried to fulfill the jqXHR object as a promise, and returned the first argument of the resolve callback.

Now, the signature for the jqXHR resolve callback is function(data, textStatus, jqXHR);, which is why the object sent to MY callback was not jqXHR as I expected, but was the first argument of the jqXHR resolve callback: data.

TL;DR: Check if the object you try to resolve your promise with has a then method, because it WILL be executed.

blue
  • 125
  • 10