40

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.

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
Chad Befus
  • 1,918
  • 1
  • 18
  • 18

1 Answers1

62

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) {
  // ...
});
Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • Have you tested your snippet ? – elad.chen Feb 01 '16 at 16:58
  • @elad.chen If you mean the stray `}` causing a syntax error, that's fixed, thank you. – Tomalak Feb 01 '16 at 17:42
  • I like this, I will test it when I get home from work and mark it as accepted after I confirm that it is correct. Thanks. – Chad Befus Feb 01 '16 at 19:57
  • This did not solve my undefined problem but I like the abstraction better. – Chad Befus Feb 02 '16 at 13:39
  • 1
    @Chad Okay. Please set up a jsFiddle that reproduces your problem, I will look into it. – Tomalak Feb 02 '16 at 14:42
  • @Tomalak I appreciate the offer but I have no way of replicating my localhost server on jsFiddle. I have reduced the problem now to barebones, I will update in the question. – Chad Befus Feb 02 '16 at 15:25
  • 1
    Any code sample that exposes the same problem will do. Without a reproduction of the issue however it's gonna be difficult. You can use [jsFiddle's Ajax responders](http://doc.jsfiddle.net/use/echo.html#json) to create the exact same setup, that's why I recommended it. – Tomalak Feb 02 '16 at 16:00
  • @Tomalak I found the root of the problem and updated in question. Now everything works as expected. Thanks. – Chad Befus Feb 02 '16 at 16:12
  • 1
    @Chad I was thinking something like that. If you really want you can look into [XDomainRequest](http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx) for IE8/IE9 support. It should be relatively easy to extend the `ajax()` function above to use that or jQuery - without a change of its external interface. – Tomalak Feb 02 '16 at 17:12