I want to send data from my application with json ajax in JavaScript. I have more than one packet of data, but when I send my data through ajax it only sends the last data packet.
For example, I send two data packets, then ajax sends two data packets but they both contain the same data(the last data packet).
Here is my code.
for(var i=0;i<data.length;) {
/*var d = new Date();
d.setTime(data[i].updated);*/
var send2 = {};
send2.nama= data[i].name;
send2.rumahsakit = data[i].hospital;
//step 1
alert("step 1"+send2.nama);
var client = "coba";
var Idku = data[i].unik;
//clientID
var request2 = {};
request2.jsonrpc = "2.0";
request2.id = "load_reg"+Idku+"";
request2.method = "registrasi:loadByClientUnik";
request2.params = [client,Idku];
//request2.params = akun.value;
var postData = JSON.stringify(request2);
var postArray = {json:postData};
$.ajax({
type: 'POST',
url: 'service.php',
data: postArray,
dataType:'json',
//async: false,
success: function(result){
alert(send2.nama);
//alert step 2;
if(result.result == -1){
//alert("-1 cuk");
var requestx = {};
requestx.jsonrpc = "2.0";
requestx.id = "store_reg";
requestx.method = "registrasi:store";
requestx.params = [send];
var postDatax = JSON.stringify(requestx);
var postArrayx = {json:postDatax};
$.ajax({
type: 'POST',
url: '/service.php',
data: postArrayx,
dataType:'json',
//async: false,
success: function(result){
//alert("sukses");
},
error: function(e){
console.log(e);
alert(e);
} });
}else{
alert(send2.nama);
var request = {};
request.jsonrpc = "2.0";
request.id = "store_reg";
request.method = "registrasi:storeById";
request.params = [result.result,send2];
var postData2 = JSON.stringify(request);
var postArray2 = {json:postData2};
$.ajax({
type: 'POST',
url: '/service.php',
data: postArray2,
dataType:'json',
//async: false,
success: function(result){
//send2 = "";
//alert("sukses ID");
},
error: function(e){
console.log(e);
alert(e);
}
});
}
},
error: function(e){
console.log(e);
alert(e);
}
});
//return false;
i++;
}
getData();
}
Example behavior: I send 2 data packets, 1st has name = 1 and the 2nd has name = 2, then I send both packets:
output :
alert step 1 print 1
alert step 1 print 2
alert step 2 print 2
alert step 2 print 2
I want this output :
alert step 1 print 1
alert step 2 print 1
alert step 1 print 2
alert step 2 print 2
}else{
alert(send2.nama);
var request = {};
request.jsonrpc = "2.0";
request.id = "store_reg";
request.method = "registrasi:storeById";
request.params = [result.result,send2];
var postData2 = JSON.stringify(request);
var postArray2 = {json:postData2};
$.ajax({
type: 'POST',
url: 'http://10.126.14.116/portable_med_services/service.php',
data: postArray2,
dataType:'json',
//context set
context: { send2: send2 },
//async: false,
success: function(result){
//send2 = "";
//alert("sukses ID");
},
error: function(e){
console.log(e);
alert(e);
}
});
This is my updated code with adding context...am I right??
update :
I already fixed this issue following this issue... jQuery ajax inside a loop problem
Your code actually sends both requests one after another (step 1), in order, like you probably want it to.
You get the first debug output due to the asynchronous nature of $.ajax() calls. They send the request and continue with the code execution-- they don't block and they don't wait for the response from the server. That's why your outer/main for loop executes all the way to the end (2 times in your case) before any response is received and the code inside the success callbacks is executed.
When the 2 responses are received, the success callbacks are executed (2 times, once for each response), however at that point in time your local variable send2.nama has the value of "2". That's why you get the output "step 2 print 2" twice, instead of "step 2 print 1" and "step 2 print 2".
This will likely also be the error cause for other requests that you make from inside the success callbacks, since you are using local variables inside the callbacks. You should be using the context parameter instead:
$.ajax({
// ...
context: { send2: send2 },
success: function (result) {
// "this" has the value of the context object
alert(this.send2.nama);
// ...
}
});
I am not sure if your intention is really to send the 2nd request only after the 1st response is already received, but if it is, then you will have to refactor the code a bit and send the 2nd request from a function invoked from inside the success callback of the 1st request.
Related
Question here about use of successive AJAX calls and async. Its a bit messed here because of how the data is set up. I need to return listings, but the sever only returns 10 per query, and the only way to determine the total number of listings is a separate query with the boolean returnTotal as true instead of false. This returns the number of listings only, and not the listing results themselves. However, if I run the calls synchronously, the variable startItem (which increments on each loop to load data starting at the next block of listings) doesn't seem to populate before the next call finishes, and results get duplicated. Any way to avoid running both as async? Apologies if my code is batshit ridiculous, as I'm relatively new to jquery.
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem=0&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=true",
dataType: "html",
async: false,
success: function(data) {
data=convert(data);
$(data).find('Listing').each(function(){
$(this).find('total').each(function(){
totalList = $(this).text();
totalList = parseInt(totalList);
totalPages = totalList/10;
});
});
},
});
for (i = 0; i < totalPages; i++){
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem="+startItem+"&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=false",
dataType: "html",
success: function(data) {
data=convert(data);
$(data).find('Listing').each(function(){
results_xml.push($(this));
});
result_index=0;
result_image_counter=1;
startItem = startItem + 10;
popResults();
},
});
}
The problem here is that you do not increment startItem until you receive a response. Your code is probably making multiple requests with startItem === 1 before the first response is even received, and so you will get some really weird behavior (probably will get duplicate responses, and you will only get the first few pages of data).
Avoid using synchronous calls because they will tie up other resources (like javascript).
In this case if you want to insure that you get the data in order, you can make it a serial chain of AJAX calls.
To get serial behavior and enjoy the benefits of AJAX, instead of using a loop make your callback function do the next AJAX request after incrementing startItem.
This is easier if you organize your code into functions. To wit:
function GetData()
{
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem="+startItem+"&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=false",
dataType: "html",
success: GetData_Callback
});
}
function GetData_Callback(data)
{
data=convert(data);
$(data).find('Listing').each(function(){
results_xml.push($(this));
});
result_index=0;
result_image_counter=1;
startItem += 10; // increment startItem
popResults();
if (startItem / 10 < totalPages)
{
GetData(); // get next "page" of data
}
}
var startItem = 1; // global variable will be mutated by GetData_Callback
GetData(); // get first "page" of data
To do this in parallel typically requires management of the parallel responses (you can use semaphores, etc.). For example (psuedo code) you could do something like this:
var pages = [];
var totalPages = GetTotalPages(); // request via ajax like you mentioned (function not shown)
var pagesLoaded = 0;
for(var i = 0; i < totalPages; i++)
{
GetData(pageIdx);
}
function GetData(pageIdx)
{
$.ajax({ ..., success: function(data){GetData_Callback(pageIdx,data);}});
}
function GetData_Callback(pageIdx, data)
{
pages[pageIdx] = data; // assign this specific page of data
pagesLoaded++;
if (pagesLoaded === totalPages)
{
// fully loaded; trigger event or call function to render, etc.
}
}
Do you just mean without the async: false?
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem=0&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=true",
dataType: "html",
success: function(data) {
console.log('test1'); // first response ok
data=convert(data);
$(data).find('Listing').each(function(){
$(this).find('total').each(function(){
totalList = $(this).text();
totalList = parseInt(totalList);
totalPages = totalList/10;
});
});
var startItem=0;
console.log(totalPages); // total page should be equal too "loop" logged
for (i = 0; i < totalPages; i++){
console.log('loop'); // enter the loop
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem="+startItem+"&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=false",
dataType: "html",
success: function(data) {
console.log('test2'); // number of test 2 = nb of loop = totalPages
data=convert(data);
$(data).find('Listing').each(function(){
results_xml.push($(this));
});
result_index=0;
result_image_counter=1;
startItem = startItem + 10;
popResults();
},
});
}
},
});
The problem here is that you do not increment startItem until you receive a response. Your code is probably making multiple requests with startItem === 1 before the first response is even received, and so you will get some really weird behavior (probably will get duplicate responses, and you will only get the first few pages of data).
Try this instead. It still uses your loop but it increments startItem in the loop before the next request is made to insure that all pages of data are requested.
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem=0&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=true",
dataType: "html",
async: false,
success: function(data) {
data=convert(data);
$(data).find('Listing').each(function(){
$(this).find('total').each(function(){
totalList = $(this).text();
totalList = parseInt(totalList);
totalPages = totalList/10;
});
});
},
});
var startItem = 1;
for (i = 0; i < totalPages; i++){
$.ajax({
type: "POST",
url:server url here,
data:"creativeID=test&CompanyId=BHSR&StartItem="+startItem+"&streetlocation="+choiceTown+"&Location="+sectCode+"&PriceMin="+choiceMin+"&PriceMax="+choiceMax+"&ListingType="+checkRB+"&OpenHouse=false&NewDev=false&AuthenticationId=id&ReturnTotal=false",
dataType: "html",
success: function(data) {
data=convert(data);
$(data).find('Listing').each(function(){
results_xml.push($(this));
});
result_index=0;
result_image_counter=1;
popResults();
},
});
// increment start item BEFORE the next request, not in the response
startItem += 10; // now the next request will be for 11, 21, 31, 41, etc...
}
You may want to get familiar with your javascript debugger to see the behavior for yourself.
I am doing an Ajax request on an XML file and mapping the XML into a JavaScript object my problem is that am logging the object and seeing the values I won't but when I try to return the values I keep getting undefined, even that all the code is inside the success callback of the AJAX request, my code is as bellow:
// Errors Object
var ErrorsObject = {};
var ErrorApplet = $('.AppletStyle1 table td');
// Ajax Request
$.ajax({
type: "GET",
url: "ECA_ADMIN_IO.xml",
dataType: "xml",
cache: false,
success: function (xml) {
$(xml).find('EcaAdminBc').each(function () {
var code = $(this).find('code').text();
var msg = $(this).find('msg').text();
ErrorsObject[code] = msg;
});
// Reformat Errors
if(ErrorApplet.length > 0) {
$(ErrorApplet).each(function(){
var Error = $(this).text();
if(Error.indexOf("SBL") >= 0){
var ErrorCode = Error.split('(')[1].replace(")","");
var ErrorText = ErrorsObject[ErrorCode];
// The Log is showing the values correctly but i cant access the object values
console.log(ErrorsObject);
// ErrorText And ErrorCode Are always undefined !!
if(typeof ErrorText != 'undefined'){
$(this).text(ErrorText);
}
}
});
}
}
});
I need additional context, but I guess what the problem is. You are trying to do some thing like this:
var myFunction = function(){
// Error Object
var ErrorsObject = {};
var ErrorApplet = $('.AppletStyle1 table td');
$.ajax(
type: "GET",
url: "ECA_ADMIN_IO.xml",
dataType: "xml",
cache: false,
success: function (xml) {
//using response to fill ErrorsObject
ErrorsObject['Ok'] = 'This key has Value!';
//more awesome code here
//... lets check again:
console.log(ErrorsObject['OK']); //Outputs 'This key has Value!'
}
);
return ErrorsObject;
};
var myAwesomeErrorObject = myFunction();
console.log(myAwesomeErrorObject['OK']); //undefined!
console.log(myAwesomeErrorObject); //Empty object!
The problem is that myFunction finished before the success callback function gets executed (the callback is asynchronous). That is why logging myAwesomeErrorObject['OK'] shows undefined. I guess that you also tried return ErrorsObject inside the success callback, but that won't work either.
In order to fix your code you must either:
Use the ErrorsObject inside the success callback (i.e. don't return it).
Call a second function from inside the success callback, passing it the ErrorsObject.
Pass a calback function to myfunction and execute it from inside the success callback.
I'm experimenting with the Rotten Tomatoes API. On a click event, a search returns JSON data for the closest matched movie title and thumbnail image to the search input.
Upon completion of that first $.ajax request, a second $.ajax request is made, using var resultID, which was declared at the top and set upon 'success' of the first $ajax request.
As of now, when I click for the first time, it runs the first request successfully, but it can't run return json.total (upon 'complete') because the resultID is returned as 'undefined'. But the second time I click, resultID has apparently been set, since it will return json.total successfully.
I'm guessing this a simple problem related to how I'm declaring and calling resultID (or the asynchronous firing of ajax), but I'm not sure what it is. Can anyone explain?
var apiKey = '***********';
var resultID = "";
$('#search-submit').click(function(){
var queryText = $('#movie-search').val();
var queryURI = encodeURI(queryText);
var searchApiRequest = "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=" + queryURI + "&page_limit=10&page=1&apikey=" + apiKey;
var reviewApiRequest = "http://api.rottentomatoes.com/api/public/v1.0/movies/" + resultID + "/reviews.json?review_type=top_critic&page_limit=10&page=1&country=us&apikey=" + apiKey;
$.ajax({
url: searchApiRequest,
type: 'GET',
dataType: 'jsonp',
error: function() {
console.log('there was error in processing the search request.');
},
success: function(json) {
var movieInfo = json.movies[0];
var noResultsMessage = 'your search returned no matches. Please try again.';
var resultTitle = movieInfo.title;
var resultThumb = movieInfo.posters.thumbnail;
var resultDesc = movieInfo.critics_consensus;
var reviewsPublicURL = movieInfo.links.reviews;
var reviewsRequest = reviewsPublicURL;
resultID = movieInfo.id; // supposed to set global var resultID to movieID
$('.search-results').find('img').attr('src',resultThumb).end().find('h1').text(resultTitle).end().find('p').text(resultDesc);
},
complete: function() {
$.ajax({
url:reviewApiRequest,
type: 'GET',
dataType: 'jsonp',
error: function(json) {
console.log('for whatever reason, we could not find any reviews of this movie');
},
success: function(json) {
console.log(json.total);
}
});
}
});
});
You need to not only set a global resultID but also refresh a reviewApiRequest as well. It doesn't magically change its value by itself when you update resultID.
I am completely new to Javascript/jquery world and need some help. Right now, I am writing one html page where I have to make 5 different Ajax calls to get the data to plot graphs. Right now, I am calling these 5 ajax calls like this:
$(document).ready(function() {
area0Obj = $.parseJSON($.ajax({
url : url0,
async : false,
dataType : 'json'
}).responseText);
area1Obj = $.parseJSON($.ajax({
url : url1,
async : false,
dataType : 'json'
}).responseText);
.
.
.
area4Obj = $.parseJSON($.ajax({
url : url4,
async : false,
dataType : 'json'
}).responseText);
// some code for generating graphs
)} // closing the document ready function
My problem is that in above scenario, all the ajax calls are going serially. That is, after 1 call is complete 2 starts, when 2 completes 3 starts and so on .. Each Ajax call is taking roughly around 5 - 6 sec to get the data, which makes the over all page to be loaded in around 30 sec.
I tried making the async type as true but in that case I dont get the data immediately to plot the graph which defeats my purpose.
My question is:
How can I make these calls parallel, so that I start getting all this data parallely and my page could be loaded in less time?
Thanks in advance.
Using jQuery.when (deferreds):
$.when( $.ajax("/req1"), $.ajax("/req2"), $.ajax("/req3") ).then(function(resp1, resp2, resp3){
// plot graph using data from resp1, resp2 & resp3
});
callback function only called when all 3 ajax calls are completed.
You can't do that using async: false - the code executes synchronously, as you already know (i.e. an operation won't start until the previous one has finished).
You will want to set async: true (or just omit it - by default it's true). Then define a callback function for each AJAX call. Inside each callback, add the received data to an array. Then, check whether all the data has been loaded (arrayOfJsonObjects.length == 5). If it has, call a function to do whatever you want with the data.
Let's try to do it in this way:
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
var area0Obj = {responseText:''};
var area1Obj = {responseText:''};
var area2Obj = {responseText:''};
var url0 = 'http://someurl/url0/';
var url1 = 'http://someurl/url1/';
var url2 = 'http://someurl/url2/';
var getData = function(someURL, place) {
$.ajax({
type : 'POST',
dataType : 'json',
url : someURL,
success : function(data) {
place.responseText = data;
console.log(place);
}
});
}
getData(url0, area0Obj);
getData(url1, area1Obj);
getData(url2, area2Obj);
});
</script>
if server side will be smth. like this:
public function url0() {
$answer = array(
array('smth' => 1, 'ope' => 'one'),
array('smth' => 8, 'ope' => 'two'),
array('smth' => 5, 'ope' => 'three')
);
die(json_encode($answer));
}
public function url1() {
$answer = array('one','two','three');
die(json_encode($answer));
}
public function url2() {
$answer = 'one ,two, three';
die(json_encode($answer));
}
So there, as you can see, created one function getData() for getting data from server and than it called 3 times. Results will be received in asynchronous way so, for example, first can get answer for third call and last for first call.
Console answer will be:
[{"smth":1,"ope":"one"},{"smth":8,"ope":"two"},{"smth":5,"ope":"three"}]
["one","two","three"]
"one ,two, three"
PS. please read this: http://api.jquery.com/jQuery.ajax/ there you can clearly see info about async. There default async param value = true.
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active...
The following worked for me - I had multiple ajax calls with the need to pass a serialised object:
var args1 = {
"table": "users",
"order": " ORDER BY id DESC ",
"local_domain":""
}
var args2 = {
"table": "parts",
"order": " ORDER BY date DESC ",
"local_domain":""
}
$.when(
$.ajax({
url: args1.local_domain + '/my/restful',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
type: "POST",
dataType : "json",
contentType: "application/json; charset=utf-8",
data : JSON.stringify(args1),
error: function(err1) {
alert('(Call 1)An error just happened...' + JSON.stringify(err1));
}
}),
$.ajax({
url: args2.local_domain + '/my/restful',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
type: "POST",
dataType : "json",
contentType: "application/json; charset=utf-8",
data : JSON.stringify(args2),
error: function(err2) {
calert('(Call 2)An error just happened...' + JSON.stringify(err2));
}
})
).then(function( data1, data2 ) {
data1 = cleanDataString(data1);
data2 = cleanDataString(data2);
data1.forEach(function(e){
console.log("ids" + e.id)
});
data2.forEach(function(e){
console.log("dates" + e.date)
});
})
function cleanDataString(data){
data = decodeURIComponent(data);
// next if statement was only used because I got additional object on the back of my JSON object
// parsed it out while serialised and then added back closing 2 brackets
if(data !== undefined && data.toString().includes('}],success,')){
temp = data.toString().split('}],success,');
data = temp[0] + '}]';
}
data = JSON.parse(data);
return data; // return parsed object
}
In jQuery.ajax you should provide a callback method as below:
j.ajax({
url : url0,
async : true,
dataType : 'json',
success:function(data){
console.log(data);
}
}
or you can directly use
jQuery.getJSON(url0, function(data){
console.log(data);
});
reference
You won't be able to handle it like your example. Setting to async uses another thread to make the request on and lets your application continue.
In this case you should utilize a new function that will plot an area out, then use the callback functions of the ajax request to pass the data to that function.
For example:
$(document).ready(function() {
function plotArea(data, status, jqXHR) {
// access the graph object and apply the data.
var area_data = $.parseJSON(data);
}
$.ajax({
url : url0,
async : false,
dataType : 'json',
success: poltArea
});
$.ajax({
url : url1,
async : false,
dataType : 'json',
success: poltArea
});
$.ajax({
url : url4,
async : false,
dataType : 'json',
success: poltArea
});
// some code for generating graphs
}); // closing the document ready function
It looks like you need to dispatch your request asynchronously and define a callback function to get the response.
The way you did, it'll wait until the variable is successfully assigned (meaning: the response has just arrived) until it proceeds to dispatch the next request. Just use something like this.
$.ajax({
url: url,
dataType: 'json',
data: data,
success: function(data) {
area0Obj = data;
}
});
This should do the trick.
Here's a solution to your issue: http://jsfiddle.net/YZuD9/
you may combine all the functionality of the different ajax functions into 1 ajax function, or from 1 ajax function, call the other functions (they would be private/controller side in this case) and then return the result. Ajax calls do stall a bit, so minimizing them is the way to go.
you can also make the ajax functions asynchronous (which then would behave like normal functions), then you can render the graph at the end, after all the functions return their data.
I am trying to run through a array send to a php file and on a callback send the next value after the php has completed its download. Here what i have so far.
my array come through as follows.
["http://example.com/test1.zip", "http://example.com/test2.zip", "http://example.com/test3.zip", "http://example.com/test4.zip", "http://example.com/test5.zip"]
above is the output from console.log(values); below. it grabs some urls from checkbox values.
$('.geturls').live('click',function(){
var values = new Array();
$.each($("input[name='downloadQue[]']:checked"), function() {
values.push($(this).val());
ajaxRequest($(this).val(),function(response){
console.log(response);
});
});
console.log(values);
return false;
});
this then calls a ajax function which i am trying to do a callback on.
function ajaxRequest(urlSend,callback){
var send = {
url: urlSend
}
$.ajax({
type: "POST",
url: "<?php echo base_url(); ?>index.php/upload",
data: send,
//dataType: "json",
//timeout: 8000,
beforeSend: function() {
},
success: function(response) {
callback('added');
},
error: function (response) {
callback('false');
}
});
}
this will then send to a php file.
function upload(){
$output = shell_exec("wget {$_POST['url']} 2>&1");
return true;
}
What i am trying to do is after the callback from one url which it has download fully then grab the next value from the array and download that url and so on until all the urls in the array are downloaded fully.
at the moment it just downloads the first value and then crashes because it doesn't restart the loop after a return value of true is returned.
Hope this makes sense to someone just looking for some help on the best way to loop through an array of values with a callback after complete.
May be this structure can help you. In this variant you go next URL only after successful completion of the previous Ajax call.
var arr = ['url0','url1','url2','url3'];
var index = 0;
function Run(){
DoAjax(arr[index]);
}
function Next( ){
if(arr.count = index-1)
{
index =0;
return;
}else{
DoAjax(arr[index ]);
}
}
function DoAjax(url){
$.ajax({
type: "POST",
url: url,
data: send,
beforeSend: function() {
},
success: function(response) {
index ++;
Next();
// Addition logic if needed
},
error: function (response) {
}
});
}
Run()
Now that I have a bit more time, I thought it would be good to show an alternative which takes advantage of the fact that jquery ajax is now implemented as a deferred. Meaning you can use pipe chaining to do all the work for you. I've also eliminated the callbacks by taking advantage of the deferred behavior.
This should give you the idea.
// Use jquery deferred pipe chaining to force
// async functions to run sequentially
var dfd = $.Deferred(),
dfdNext = dfd,
x,
values = [],
// The important thing to understand here is that
// you are returning the value of $.ajax to the caller.
// The caller will then get the promise from the deferred.
ajaxRequest = function (urlSend) {
var send = {
url: urlSend
}
return $.ajax({
type: "POST",
url: "<?php echo base_url(); ?>index.php/upload",
data: send,
});
};
// Starts things running. You should be able to put this anywhere
// in the script, including at the end and the code will work the same.
dfd.resolve();
// Deferred pipe chaining. This is the main part of the logic.
// What you want to note here is that a new ajax call will
// not start until the previous
// ajax call is completely finished.
// Also note that we've moved the code that would
// normally be in the callback.
// Finally notice how we are chaining the pipes by
// replacing dfdNext with the return value from the
// current pipe.
for (x = 1; x <= 4; x++) {
values.push(x);
dfdNext = dfdNext.pipe(function () {
var value = values.shift();
return requestAjax(value).
done(function(response) {
// Code here that you would have
// put in your callback.
console.log(response);
}).
fail(function(response) {
console.log(response);
};
});
}
Working example you can play with on jsFiddle.