Implement promises in AJAX requests


#1

Is there a way, how multiple AJAX requests (app.request) can be chained by using promises?
Tried using deferreds and the following syntax, where “deferreds” is an XHR object from app.request, but seems like it does not work.

$$.when.apply(null, deferreds).done(function() {
//another AJAX request
})

Thank you in advance!


#2

You can either promise wrap f7’s request methods like so or use the Fetch API which has decent support. Remember that in f7 the promise only resolves when the request is >= 200 && < 300 vs fetch which only rejects on network failure.

function request(options)
{
	if(options.timeout === undefined) options.timeout = 10000;
	if(options.dataType === undefined) options.dataType = 'json';

	return new Promise((resolve, reject) =>
	{
		options.error = function(xhr, status)
		{
			reject(xhr, status);
		};
		options.success = function(data, status, xhr)
		{
			resolve(data, status, xhr);
		};

		f7.request(options);
	});
}

request.get = function(options)
{
	options.method = 'GET';
	return request(options);
};

request.post = function(options)
{
	options.method = 'POST';
	return request(options);
};

request.delete = function(options)
{
	options.method = 'DELETE';
	return request(options);
};

request.get({ url: '/test' }).then(console.log.bind(console)).catch(console.error.bind(console));

#3

Thanks for the reply!

While waiting for the replies, I was trying out the following approach:
I have two separate AJAX calls (POST) that performs creation/update of many items in Sharepoint list.
I pass an array with item IDs to both of those AJAX calls and process them with .forEach, pushing each XHR to a deferred object.

Here’s the function of my AJAX post:

function myfunc(args) {
   var deferreds = [];
   deferreds.push(
     app.request({
        //AJAX post
     });
  )

return deferreds
}

I then try to chain both of those requests in a following way:

var mydeferreds = myfunc(ids)
var firstPromise = Promise.resolve(mydeferreds);
firstPromise.then(function(){
   var mydeferreds2 = myfunc(anotherids)
   var secondPromise = Promise.resolve(mydeferreds2);
   secondPromise.then(function(){
      //success, reload the route
   })
})

However, the //success, reloat the route action is sometimes executed before all the AJAX posts are completed and both promises are resolved.
It there something wrong in the approach that I’m trying to use, or it’s simply not supported to chain the requests this way?


#4

Not quite sure what you are doing there. :slight_smile: Deferred’s don’t work unless you implement them which f7 does not (as far as I know)… maybe that’s just how you name them. If you want to execute an array of promises sequentially, you can use Array.reduce. See here.


#5

Tried to implement array.reduce in a following way, however despite all async POST requests are not yet executed, I already receive the success alert.
Am I doing something in a wrong way here?

var arrayOfFunctions = [ function() { myfunc(args) }, function() { myfunc(args) } ] 
      
      arrayOfFunctions.reduce((p, fn, index) => {
          return p.then(val => {
              return fn(val);
          });
      }, Promise.resolve()).then(result => {
            alert("Success!")
      }).catch(err => {
        console.log("Error")
      });