Skip to content

Instantly share code, notes, and snippets.

@romaricpascal
Created March 5, 2019 13:43
Show Gist options
  • Save romaricpascal/09015901cfb48f216bee18cdd0343c45 to your computer and use it in GitHub Desktop.
Save romaricpascal/09015901cfb48f216bee18cdd0343c45 to your computer and use it in GitHub Desktop.
Get a Promise out of an XHR
function send(
url,
{ method = 'GET', data, headers = {}, user, password, ...opts } = {}
) {
const xhr = new XMLHttpRequest();
const promise = new Promise((resolve, reject) => {
xhr.open(method, url, true, user, password);
xhr.addEventListener('load', resolve);
xhr.addEventListener('error', reject);
xhr.addEventListener('abort', reject);
xhr.addEventListener('timeout', reject);
Object.entries(headers).forEach(([name, value]) =>
xhr.setRequestHeader(name, value)
);
Object.entries(opts).forEach(([name, value]) => {
xhr[name] = value;
});
xhr.send(data);
});
// Expose the xhr to allow abortion and listening to other events
promise.xhr = xhr;
return promise;
}
@romaricpascal
Copy link
Author

romaricpascal commented Mar 5, 2019

A little more than 20 lines (of ES6) to get a Promise (for a ProgressEvent) out of XHRs.

From there, wrap it as needed to get whichever processing you want on the input (eg. encode data as query parameters if the method is GET) or the output (eg. reject non-success status codes).

function withNonSuccessRejection(fn) {
  return function(url, options) {
    return fn(url, options).then(e => {
      if (e.target.status >= 200 && e.target.status < 300) {
         return e;
      }
      return Promise.reject(e);
    });
  }
}

const customSend = withNonSuccessRejection(send);

@Andrewsuares
Copy link

Hello, can you add POST to a XMLHttpRequest with a Promise?

@romaricpascal
Copy link
Author

Probably seeing this too late, but you can use the method argument of the function to pick which HTTP method to use when sending the request :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment