jQuery ajax with ES6 Promises

Chad Befus picture Chad Befus · Feb 1, 2016 · Viewed 29.2k times · Source

I am trying to make a post request via jQuery using an ES6 promise:

I have a function:

getPostPromise(something, anotherthing) {
  return new Promise(function(resolve, reject) {
    $.ajax({
      url: someURL,
      type: 'post',
      contentType: 'application/json; charset=utf-8',
      data: JSON.stringify(
        something: something,
        anotherthing: anotherthing
      }),
      dataType: 'json',
      success: resolve,
      error: reject
    });
  });
}

and I call it like so:

getPostPromise(
  'someFooStuff',
  'someBarStuff'
).then(
  function(returnedData) {
    console.log("Good: ", returnedData);
  },
  function(responseObject) {
    console.log("Bad: ", responseObject);
  }
).catch(
  function(errorThrown) {
    console.log("Exception: ", errorThrown);
  }
);

My server is returning a response as expected with the request body being in JSON format but my console output is:

Good: undefined

Why am I not getting the returned data?

Thanks to anyone/everyone for any help.

--- UPDATE EDIT ---

I have reduced my js to only:

import $ from 'jquery';
$.get('http://localhost:8008/api/user')
  .done(function(data) {
    console.log(data);
  });

I still get undefined as output. If I open up the request in the network tab I can see the response object with the correct data. The request is made, my server is happy and responds, and the results are in my browser but the data parameter of done is undefined. I am stumped.

--- UPDATE 2 - SOLUTION FOUND ---

I discovered that the problem was with using: https://github.com/jpillora/xdomain to get around CORS. It would seem that that library screws up passing back values somehow. I have removed it and will implement CORS properly and to hell with browsers that don't support it.

Answer

Tomalak picture Tomalak · Feb 1, 2016

jQuery Ajax methods return promises themselves, you don't need to wrap them at all.

But you can, of course, do it for consistency with the ES6 promise API.

UPDATE jQuery 3.0+ implements the Promise/A+ API, so there is no reason anymore to wrap anything in modern jQuery. Read up on the peculiarities of jQuery's promise implementation prior to version 3.0.

For jQuery versions before 3.0, I would decouple it more than you did:

function ajax(options) {
  return new Promise(function (resolve, reject) {
    $.ajax(options).done(resolve).fail(reject);
  });
}

and

ajax({
  url: someURL,
  type: 'post',
  contentType: 'application/json; charset=utf-8',
  data: JSON.stringify({
    something: something,
    anotherthing: anotherthing
  })
}).then(
  function fulfillHandler(data) {
    // ...
  },
  function rejectHandler(jqXHR, textStatus, errorThrown) {
    // ...
  }
).catch(function errorHandler(error) {
  // ...
});