ded / reqwest

browser asynchronous http requests
2.94k stars 343 forks source link

*really* make promises chainable? #189

Open togakangaroo opened 9 years ago

togakangaroo commented 9 years ago

I see this issue and the associated PR but it doesn't seem to make promises chainable, just then methods. For example you would expect the following

let r = reqwest({url: '/api/ProspectiveCustomer', method: 'post'})
            .then(() => r.request.getResponseHeader('Location') )
            .then((url) => reqwest({url: url, type: 'json'}) )
            .then((d) => console.log("this should be json", d))

to work, but it doesn't! Seems like the second then chains the returned promise into the the next parameter. Instead it's supposed to return a new promise that resolves when everything is done.

That's the way every other promise library I've used has worked at least...

ded commented 9 years ago

since this isn't a legit promise library... it's in desperate need of one. i'm open to suggestions for light-weight promise libs

joshq00 commented 9 years ago

If you're using a library, browser that supports it, or polyfill, this has been my workaround:

// overwrite reqwest
// or you could make it a separate fn
( _reqwest => {
    // wrap `reqwest` with a deferred
    reqwest = ( ...args ) => {
        let d = Promise.defer();
        _reqwest( ...args ).then( d.resolve, d.reject );
        return d.promise;
    };
} )( reqwest );

let r = reqwest( { url, method, type, data } )
    .then( res => res.getResponseHeader( 'Location' ) )
    .then( url => ( { url, type } ) )
    .then( reqwest );

r.then( data => console.log( data ) );
odzb commented 9 years ago

It's even simpler than that:

Promise.resolve(reqwest(...))
raptoria commented 8 years ago

this might help someone... you need to pass the "r" object to Promise.resolve

    getJSON(data_url) {
          let r = 
              reqwest({
                  url: data_url,
                  method: 'GET',
                  crossOrigin: true,
                  type: 'json',
                  contentType: 'application/json', 
                  headers: {
                    'Authorization': 'JWT ' + LoginStore.jwt
                  }
              })
           return r;
       }

      requestMultiData(urls, name){
        let requests = [];
        for (let url of urls){
           let promise = Promise.resolve(this.getJSON(url));
           requests.push(promise);
        }

        Promise.all(requests).then(function(values) { 
          console.log(name +" "+values); 
        }).catch(function(e) {
                 console.log("Error retrieving data");
         });
      }
kmkr commented 8 years ago

Wrap reqwest like this and you'll get actual promises:

function reqwestAsPromise(opts) {
    return new Promise((resolve, reject) => {
        reqwest({
            ...opts,
            success: resolve,
            error: response => {
                if (response.responseText) {
                    return reject(JSON.parse(response.responseText));
                }

                return reject(response);
            }
        })
    });
}