How to show progress bar when calling AJAX? - javascript

I am developing a mobile app using phonegap (JQ + Html ). In my app, consuming REST webservice using AJAX calls.When service invoke, I am showing a progress bar animated GIF image . The problem is, browser freezes when calling AJAX. So the progress bar is not showing.
In ‘beforeSend’ i am showing the progress bar image and after ‘complete’ i am hiding the progress bar image.
I am also trying async: true . But it execute service as asynchronously. In my app, asynchronous execution is not suit. Because asynchronous execution will not wait for ajax executing. My app should wait until the ajax execution complete. In that process time I want show progress bar.
Here is my code.
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json",
accepts: "application/json",
beforeSend: function() {
StartPBar():
},
data: JSON.stringify(RQ),
async: false,
url: URL,
complete: function() {
stopPBar();
},
success: function(res, status, xhr) {
try {
RS = res;
} catch (e) {
alert(e);
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Excpetion " + errorThrown + XMLHttpRequest);
}
});
Any suggestion to show the progress bar stay on screen until the process is fully complete? Any help would be appreciated. Thanks

Make sure you verify your javascript code.
Remove this code.
beforeSend: function() {
StartPBar():
},
Replace your jquery mobile with this one jQuery Mobile 1.4.0-rc.1
http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.js
Replace your code with this one.
$.mobile.loading('show');
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json",
accepts: "application/json",
data: JSON.stringify(RQ),
async: false,
url: URL,
complete: function() {
$.mobile.loading('hide');
},
success: function(res, status, xhr) {
try {
$.mobile.loading('hide');
RS = res;
} catch (e) {
alert(e);
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
$.mobile.loading('hide');
alert("Excpetion " + errorThrown + XMLHttpRequest);
}
});

Try to set async: true, the async: false will freeze the browser until the request is completed. Also move the async: true before beforeSend method.
The async: true, when supported by browser, basically means: browser will send data asynchronous and will not block or wait other actions from executing. This is the only in my opinion way to show the progress bar indicator. Because (from the documentation):
Note that synchronous requests may temporarily lock the browser,
disabling any actions while the request is active.

If you want to wait until ajax requests done, you can do it also with async:true like;
StartPBar():
$.when(runAjax()).done(function(result) {
// result conatins responseText, status, and jqXHR
stopPBar();
});
function runAjax() {
return $.ajax({
type: "POST",
dataType: "json",
contentType: "application/json",
accepts: "application/json",
data: JSON.stringify(RQ),
async: true,
url: URL,
success: function (res, status, xhr) {
try {
RS = res;
}
catch (e) {
alert(e);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("Excpetion " + errorThrown + XMLHttpRequest);
}
});
}
In this example, when ajax request completed, progressbar stop function will be called.

Related

Jquery Send Ajax and no wait response for sending other ajax

I have an ajax that call to a server and run a long process (this process is writing the status on a database).
I have other ajax (recursively) to get the status of the long process and set the params on a Progress Bar.
My problem is that the second ajax not start until the first one finishes. Is there a way to send the first ajax and no wait for a response?
Any ideas?
I appreciate any suggestion, I am a little bit tired about this issue.
If there is another method to send a long process and get the status of the long process, tell me, please.
Thank you!
This is my code, in case it's helps
executeProgressBar(1, token);
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
processData: false,
contentType: false,
cache: false,
url: "/long_process",
data: form_data,
success: function (response) {
//NOTHING
}
});
function executeProgressBar(start, token) {
if (start == 1) {
//reset progress bar
$('.progress-bar').css('width', '0%');
$('.progress-bar').text('0%');
$('.progress-bar').attr('data-progress', '0');
}
$.ajax({
type: "POST",
url: "/progress_bar_status",
data: { token: token, sleep: 0 },
success: function (response) {
$('.progress-bar').css('width', response['percentage'] + '%');
$('.progress-bar').text(response['percentage'] + '%');
$('.progress-bar').attr('data-progress', response['percentage']);
$('#done').text(response['executed']);
$('.execute-time').text('tiempo');
if (response.percentage == 100) {
$('.end-process').show();
} else {
executeProgressBar(0, token);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
if (textStatus == 'parsererror') {
textStatus = 'Technical error: Unexpected response returned by server. Sending stopped.';
}
alert(textStatus);
}
});
}
EDIT
I solved whit this code on the server side - php
/************** Close connection and return echo message **************/
ob_end_clean();
header("Connection: close");
ignore_user_abort(true);
ob_start();
echo('text response to ajax');
$size = ob_get_length();
header("Content-Length: $size");
ob_end_flush();
flush();
// if you're using sessions, this prevents subsequent requests
// from hanging while the background process executes
if (session_id()) {
session_write_close();
}
/************** background process starts here **************/
View in this post: How do I close a connection early?
You are calling the executeProgressBar instantly instead of waiting for the first AJAX call to complete. Call the executeProgressBar function in the success method callback and pass it to the executeProgressBar function and modify the parameters like the example below.
Be sure to build a check in that lets the recursive function know when to stop.
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
processData: false,
contentType: false,
cache: false,
url: "/long_process",
data: form_data,
success: function (response) {
executeProgressBar(1, token, response);
}
});
function executeProgressBar(start, token, response) {
if (start == 1) {
//reset progress bar
$('.progress-bar').css('width', '0%');
$('.progress-bar').text('0%');
$('.progress-bar').attr('data-progress', '0');
}
$.ajax({
type: "POST",
url: "/progress_bar_status",
data: {token: token, sleep: 0},
success: function (response) {
$('.progress-bar').css('width', response['percentage'] + '%');
$('.progress-bar').text(response['percentage'] + '%');
$('.progress-bar').attr('data-progress', response['percentage']);
$('#done').text(response['executed']);
$('.execute-time').text('tiempo');
if (response.percentage == 100) {
$('.end-process').show();
} else {
executeProgressBar(0, token, response);
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
if (textStatus == 'parsererror') {
textStatus = 'Technical error: Unexpected response returned by server. Sending stopped.';
}
alert(textStatus);
}
});
}

jQuery synchronous call

For rendering a dialog, i have two jQuery ajax calls. One to load the buttons and another to load the body of the dialog. I first call the function that loads the buttons (asychronous ajax call)
$.ajax({
type: "POST",
//async: false,
url: action,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (result) {
$('#dialogButtons').html(result);
},
error: function (req, status, error) {
alert(req + " " + error + " " + status);
}
Then i call another similar ajax call to load the body of the dialog in asychronous fashion.
The buttons doesn't always show up. So I made
$.ajaxSetup({ async: false });
$.ajax({
asyc: false,
url: action
})
$.ajaxSetup({ async: true });
as per other stack overflow experts. i am seeing mixed opinions on this approach.
Please help me with the standard way to achieve this.
Do the second AJAX call in the success function of the first.
$.ajax({
type: "POST",
url: action,
dataType: "html",
success: function(result) {
$('#dialogButtons').html(result).hide(); // Will show it after 2nd AJAX call
$.ajax({
type: "POST",
dataType: "html",
url: otheraction,
success: function(result) {
if (result) {
$("#dialog").html(result);
$("#dialogButtons").show();
}
}
});
},
error: function(req, status, error) {
alert(req + " " + error + " " + status);
}
});
You also shouldn't have contentType: "application/json". You're not sending any post data, and $.ajax doesn't send JSON; if you had post data, it would be URL-encoded.

Issues executing an AJAX request

I am building a Facebook messenger bot. I got to a point where I need to show a webview. This webview does some payment processing and on success, I call a Messenger SDK's function to close the webview and then do an Ajax call to continue messaging the user. Now I have an issue, the webview does not close until the ajax has finished executing i.e. sending the messages to the user. If I place the Messenger close function outside the ajax call, the webview closes but the ajax is not executed. Please how do I close the webview and then continue executing the ajax request.This is what I am currently doing:
$.ajax({
type: 'POST',
dataType: 'JSON',
url: '/api/payment/'+userId+'/'+payRef,
data: 'userId='+userId,
success: function (data) {
console.log(data);
MessengerExtensions.requestCloseBrowser();
}
})
I don't know if that can solve your problem, but you can try this:
$.ajax({
type: 'POST',
dataType: 'JSON',
url: '/api/payment/'+userId+'/'+payRef,
data: 'userId='+userId,
beforeSend: function() {
MessengerExtensions.requestCloseBrowser();
},
success: function (data) {
console.log(data);
}})
In theory, the window will close before the request init.
I don't know if I understood right, but did you try the beforeSend and complete functions from ajax?
$.ajax({
type: 'POST',
dataType: 'JSON',
url: '/api/payment/'+userId+'/'+payRef,
data: 'userId='+userId,
beforeSend: function(jqXHR, settings) {
// Action before send the request to the url
},
success: function (data) {
// Action if the process in the url url don't throw any errors
},
complete: function(jqXHR, textStatus) {
// Action when the request is returned to application
},
error: function(jqXHR, textStatus, errorThrown) {
// I would recommend you always use the error function.
}
})

Reliably complete Ajax request on page unload

I have a html/javascript application. When user refreshes the page or close the page i need to make a ajax request and then close the application.
I am using page unload event for this purpose.
I am calling
window.onbeforeunload=beforeFunction;
beforeFunction will make the ajax request. But when i check in fiddler i dont see the ajax request. However if i debug the application and execute each line with f10 then i see the ajax request in fiddler.
thats how my ajax request is formed:
$.ajax({
url: url,
type: "GET",
contentType: "application/json",
async: false,
crossDomain: true,
dataType: 'jsonp',
success: function(json){
alert("success: " + json);
},
error: function(xhr, statusText, err) {
alert("Error:" + xhr.status);
}
});
$(window).on('beforeunload' function() {
$.ajax({
url: url,
type: "GET",
contentType: "application/json",
async: false,
crossDomain: true,
dataType: 'jsonp',
success: function(json){
alert("success: " + json);
},
error: function(xhr, statusText, err) {
alert("Error:" + xhr.status);
}
});
});
Try this....

Jquery jsonp response error - Callback was not called

I'm trying to get some information from a different domain, the domain allows only jsonp call - others get rejected. How can I get the content instead of execution? Because I get an error in response. I don't need to execute it, I just need it in my script. In any format (the response is json but js doesn't understand it).
I can't affect on that domain so it's impossible to change something on that side.
Here's my code:
$.ajax({
url: url + '?callback=?',
crossDomain: true,
type: "POST",
data: {key: key},
contentType: "application/json; charset=utf-8;",
async: false,
dataType: 'jsonp',
jsonp: 'callback',
jsonpCallback: 'jsonpCallback',
error: function(xhr, status, error) {
console.log(status + '; ' + error);
}
});
window.jsonpCallback = function(response) {
console.log('callback success');
};
There are a few issues with your $.ajax call.
$.ajax({
url: url + '?callback=?',
// this is not needed for JSONP. What this does, is force a local
// AJAX call to accessed as if it were cross domain
crossDomain: true,
// JSONP can only be GET
type: "POST",
data: {key: key},
// contentType is for the request body, it is incorrect here
contentType: "application/json; charset=utf-8;",
// This does not work with JSONP, nor should you be using it anyway.
// It will lock up the browser
async: false,
dataType: 'jsonp',
// This changes the parameter that jQuery will add to the URL
jsonp: 'callback',
// This overrides the callback value that jQuery will add to the URL
// useful to help with caching
// or if the URL has a hard-coded callback (you need to set jsonp: false)
jsonpCallback: 'jsonpCallback',
error: function(xhr, status, error) {
console.log(status + '; ' + error);
}
});
You should be calling your url like this:
$.ajax({
url: url,
data: {key: key},
dataType: 'jsonp',
success: function(response) {
console.log('callback success');
},
error: function(xhr, status, error) {
console.log(status + '; ' + error);
}
});
JSONP is not JSON. JSONP is actually just adding a script tag to your <head>. The response needs to be a JavaScript file containing a function call with the JSON data as a parameter.
JSONP is something the server needs to support. If the server doesn't respond correctly, you can't use JSONP.
Please read the docs: http://api.jquery.com/jquery.ajax/
var url = "https://status.github.com/api/status.json?callback=apiStatus";
$.ajax({
url: url,
dataType: 'jsonp',
jsonpCallback: 'apiStatus',
success: function (response) {
console.log('callback success: ', response);
},
error: function (xhr, status, error) {
console.log(status + '; ' + error);
}
});
Try this code.
Also try calling this url directly in ur browser and see what it exactly returns, by this way You can understand better what actually happens :).
The jsonpCallback parameter is used for specifying the name of the function in the JSONP response, not the name of the function in your code. You can likely remove this; jQuery will handle this automatically on your behalf.
Instead, you're looking for the success parameter (to retrieve the response data). For example:
$.ajax({
url: url,
crossDomain: true,
type: "POST",
data: {key: key},
contentType: "application/json; charset=utf-8;",
async: false,
dataType: 'jsonp',
success: function(data){
console.log('callback success');
console.log(data);
}
error: function(xhr, status, error) {
console.log(status + '; ' + error);
}
});
You can also likely remove the other JSONP-releated parameters, which were set to jQuery defaults. See jQuery.ajax for more information.

Categories

Resources