Today I had a very interesting case where we needed to get a specific amount of SVG files with ajax calls that were to be processed once after all of the requests are done.
I was familiar with the $.when and used it before but only in casese where the number of the calls were fixed amount.
So something like this:
$.when( $.ajax( 'first.svg' ), $.ajax( 'second.svg' ) ).done( function( ajax1, ajax2 ) { // do stuff with both things.. as ajax1[0] is the svg document // for the first.svg and ajax2[0] is the svg document for the // second.svg });
It’s clear that we are going to use something similar.. so we tried putting the ajax requests into an array so we can dinamically add them.
// svgUrlArray is an existing array with all the urls of the svgs // we create a new array with all the ajax calls var svgAjaxArray = []; for( var svgIndex = 0; svgIndex < svgUrlArray.length; svgIndex++ ) { svgAjaxArray.push( $.ajax( svgUrlArray[ svgIndex ] ) ); }
Now we give the array to the $.when
$.when( svgAjaxArray ).done( function() { // this is executed a bit too early });
The done function is executed too early. Why?
Because the Array is not a Deffered – it’s just an Array and it gets its value immediatley. So the done is executed right away.
So what’s the easiest solution?
$.when.apply( $, svgAjaxArray ).done( function() { // Now we're talking ;) // You must use the arguments variable to get all the entries // because you don't know what is the length of the ajaxArray });
So now we can do any amount of async requests and process them after all of them are done. Hooraaay!