Integrating promises array with RSVP.js using jQuery $ .ajax

Re: https://github.com/tildeio/rsvp.js

What is the best way to integrate RSVP.js with jQuery $ .ajax? After some readings and research, I see that Ember has an active development of the wrapper around it ... https://github.com/emberjs/ember.js/pull/4148

Anyone with experience using this use case promises?

I use RSVP.js because I process the dynamic promises array through the .all () method.

Each of these promises from the array has its own promise, which is executed after it is again polled for data from the function recursively. I am having problems with how I should structure the code.

The use case, if you are interested, is that I send an AJAX request to my API for a report related to a specific resource, which returns a list of URL endpoints for which it should hit for more report data about its child Resources. Then each of these resources returns a JSON object with report data for a specific day and another URL with parameters for the next day (or a group of days). He then continues to poll data from the “next” from the same endpoint until there is nothing left.

Thanks in advance to everyone who can help!

Also, if you have any guidance on how to format this code so that it is more readable and supported, I'd love to hear.

the code:

url = "http://localhost:3000/api/foo_resources/1/reports/bar"

var headers = {
    "Accept": 'application/vnd.xps+json; version=1', // Headers for API access
    "X-User-Email": 'example@company.com',
    "X-User-Token": '1234abcd',
}

$.ajax({
    type: 'GET',
    url: url,
    headers: headers,
    dataType: 'json',
    xhrFields: {
        withCredentials: true
    }
}).then(function(response) {

    // the ajax request would return a long list of bucket like this with endpoints to hit {
    // {
    //   "buckets": [
    //     "http://localhost:3000/api/foos_nested_resources/1/reports/bar"
    //     "http://localhost:3000/api/foos_nested_resources/2/reports/bar"
    //     "http://localhost:3000/api/foos_nested_resources/3/reports/bar"
    //   ]
    // }

    var promises = response.buckets.map(function getReportData(bucket) {

        return new RSVP.Promise(function(resolve, reject) {
            var recursiveRequest = function(bucket) {
                $.ajax({
                    type: 'GET',
                    url: bucket,
                    headers: headers,
                    dataType: 'json',
                    xhrFields: {
                        withCredentials: true
                    }

            // This is the report that comes back, obviously truncated significantly for this example
            // {
            //   reports: [
            //     { id: 1, datapoint_a: 5438, datapoint_b: 1389 },
            //     { id: 2, datapoint_a: 4336, datapoint_b: 2236 }
            //   ],
            //   next: "http://localhost:3003/api/nexted_foo_resources/1/reports/bar?ends=2014-02-06&starts=2014-01-24"
            // }

                }).done(function(response) {
                    $.merge(reports, response.reports); // I could use concat here but I prefer readability

                    if (response.next) {
                        recursiveRequest(response.next);
                    } else {
                        resolve(reports);
                    }
                }).error(function(error) {
                    reject(error);
                });
            };

            recursiveRequest(bucket);
        });
    });

    RSVP.all(promises).then(function(data) {
        console.dir(data);
    }).catch(function(error) {
        console.dir(error);
    })
})
+3
source share
2

, ( API-), , : RSVP:

var initialUrl = "http://localhost:3000/api/foo_resources/1/reports/bar";

var headers = {
  "Accept": 'application/vnd.xps+json; version=1', // Headers for API access
  "X-User-Email": 'example@company.com',
  "X-User-Token": '1234abcd',
};

function rsvpAjax(opts){
  return new RSVP.promise(function(resolve, reject){
    var defaultOpts = {
      type: 'GET',
      headers: headers,
      dataType: 'json',
      xhrFields: {
        withCredentials: true
      }
    };
    $.ajax($.extend({}, defaultOpts, opts, {
      success: function(json) {
        resolve(json);
      },
      error: function(jqXhr, textStatus, errorThrown){
        reject({ jqXhr: jqXhr, textStatus: textStatus, errorThrown: errorThrown});
      }
    }));
  });
}

function requestBucket(bucket){
  return rsvpAjax({ url: bucketUrl }).then(bucketResponseProcessor(bucket));
}

function bucketResponseProcessor(bucket){
  return function(response){
    $.merge(bucket.reports, response.reports);
    if (response.next) {
      bucket.url = response.next;
      return requestBucket(bucket);
    } else {
      return bucket.reports;
    }    
  };
}

rsvpAjax({ url: initialUrl }).then(function(response) {
  return RSVP.all(response.buckets.map(function(bucketUrl){
      var bucket = { url: bucketUrl, reports: [] };
      return requestBucket(bucket).then(processBucketResponse);
  }));
}).then(function(reports) {
  console.dir(data);
}).catch(function(error) {
  console.dir(error);
});
+4

, Ember.RSVP.Promise.cast()

$.getJSON(), jQuery Ajax-, .

0

All Articles