Loader works only on the first ajax call - javascript

I want the loader to stay until the complete execution is complete and statement $("#xyzDiv").html(data) has been executed. Currently the loader gets hidden after the first ajax call. Even if i add "beforeSend: function () { $("#loader").show(); }" to GetDataList(), the loader is not staying.
$.ajax
({
type: "POST",
url: ajaxUrl,
data: dataObj,
beforeSend: function () { $("#loader").show(); },
success: function (data)
{
if (data.result)
{
GetDataList();
toastr.success(data.strMsg);
}
else
{
toastr.error(data.strMsg);
}
},
error: function (jqXHR, textStatus)
{
var msg = HandleAjaxErrorMessage(jqXHR, textStatus);
console.log(msg);
toastr.error('An error occurred. Please try again');
},
complete: function () { $("#loader").hide(); }
});
function GetDataList()
{
$.ajax
({
type: "Get",
url: ajaxUrl,
data: dataObj,
success: function (data)
{
$("#xyzDiv").html(data);
},
error: function (jqXHR, textStatus)
{
var msg = HandleAjaxErrorMessage(jqXHR, textStatus);
console.log(msg);
toastr.error('An error occurred. Please try again');
}
});
}

Related

How to avoid repeating the same $.ajax() call

I have two $.ajax() calls in my javascript code.
$.ajax({
url: 'http://localhost/webmap201/php/load_data.php',
data: {
tbl: 'district'
},
type: 'POST',
success: function(response) {
console.log(JSON.parse(response));
json_district = JSON.parse(response);
district = L.geoJSON(json_district, {
onEachFeature: return_district,
});
ctl_layers.addOverlay(district, "district", "Overlays");
ar_district_object_names.sort();
$("#text_district_find_project").autocomplete({
source: ar_district_object_names,
});
},
error: function(xhr, status, error) {
alert("Error: " + error);
}
}
);
$.ajax({
url: 'http://localhost/webmap201/php/load_data.php',
data: {
tbl: 'province'
},
type: 'POST',
success: function(response) {
console.log(JSON.parse(response));
json_province = JSON.parse(response);
province = L.geoJSON(json_province, {
onEachFeature: return_province,
});
ctl_layers.addOverlay(province, "province", "Overlays");
ar_province_object_names.sort();
$("#text_province_find_project").autocomplete({
source: ar_province_object_names,
});
},
error: function(xhr, status, error) {
alert("Error: " + error);
}
}
);
changes on both ajax are as below:
tbl: 'district' -> tbl: 'province'
json_district -> json_province
return_district -> return_province
(district, "district", "Overlays") -> (province, "province", "Overlays")
ar_district_object_names -> ar_province_object_names
$("#text_district_find_project") -> $("#text_province_find_project")
Is there a way I can call this $.ajax() inside a function with one parameter and call the function afterwards. As an example:
function lyr(shpName){
$.ajax({
url: 'http://localhost/webmap201/php/load_data.php',
data: {
tbl: `${shpName}`
},
type: 'POST',
success: function(response) {
console.log(JSON.parse(response));
json_shpName = JSON.parse(response);
shpName = L.geoJSON(json_shpName, {
onEachFeature: return_shpName,
});
ctl_layers.addOverlay(shpName, `${shpName}`, "Overlays");
ar_shpName_object_names.sort();
$("#text_shpName_find_project").autocomplete({
source: ar_shpName_object_names,
});
},
error: function(xhr, status, error) {
alert("Error: " + error);
}
}
);
}
lyr (district);
Can I use template strings? Can I use that a function inside a function. Any help would be highly appriceated.
Create a function for ajax call.
For eg.:-
function serviceajaxjson(_successfun, _failurefun, _url, _data, _async, _global) {
if (_successfun == null) _successfun = ajax_return_successfun;
if (_failurefun == null) _failurefun = ajax_return_failurefun;
if (_global != false) { _global = true; }
if (_async != false) { _async = true; }
$.ajax({
type: "POST",
url: _url,
data: _data,
global: _global,
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
async: _async,
success: _successfun,
error: ajax_return_error,
failure: _failurefun
});
}
function ajax_return_successfun(response) {
console.info("success for " + response.d);
}
function ajax_return_failurefun(response) {
console.error("failuer occoured for " + response);
}
function ajax_return_error(response) {
console.warn("error occoured for " + response);
}
// // // call the above function
function myResponseFn(response){
if(response.data){
// // your code...
}
}
var data = "{'tbl': 'district'}";
serviceajaxjson(myResponseFn,myResponseFn,"http://localhost/webmap201/php/load_data.php",data);
If you're using latest version of popular browser (IE's dead, use Edge instead), then the simplest answer is yes. You might need some tweaking on the parameters and its use, but it should work

Javascript wait until localization resources are pulled from server

I have the following Javascript code:
(function (document, window, $) {
'use strict';
var Site = window.Site;
var translations = [];
$(document).ready(function ($) {
translations = Site.getTranslations();
Site.run(); // glogal site setup
});
// Init function
// ------------------------
(function () {
$("#cbolanguage").change(function (e) {
// start ajax request
$.ajax({
url: url.switchLang,
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ lang: e.target.value }),
dataType: "json",
success: function (data, textStatus, jqXHR) {
if (data.success) {
location.reload();
}
},
error: function (jqXHR, textStatus, errorThrown) {
}, complete: function () {
}
});
});
function init() {
$('#btn-login').click(function (e) {
e.preventDefault();
$('#form-login').data('formValidation').validate();
if (!$('#form-login').data('formValidation').isValid()) return;
});
init();
}
})();
// Validataion
// ------------------------
(function () {
$('#form-login').formValidation({
framework: "bootstrap",
icon: null,
fields: {
Login: {
validators: {
notEmpty: {
message: translations.text1 // NEED TO WAIT UNTIL THIS HAS A VALUE
}
}
},
Password: {
validators: {
notEmpty: {
message: translations.text1 // NEED TO WAIT UNTIL THIS HAS A VALUE
}
}
},
},
err: {
clazz: 'text-help'
},
row: {
invalid: 'has-error'
}
}).on('err.field.fv', function (e, data) {
data.fv.disableSubmitButtons(false);
})
.on('success.field.fv', function (e, data) {
data.fv.disableSubmitButtons(false);
});;
})();
})(document, window, jQuery);
In the document.ready() I call the function:
translations = Site.getTranslations();
This function code is:
getTranslations: function () {
var returnData = [];
// start ajax request
$.ajax({
url: appData.getTranslations,
type: 'POST',
contentType: 'application/json',
dataType: "json",
async: false, // SYNCRONOUS CALL
success: function (data, textStatus, jqXHR) {
if (data.success) {
returnData = data.data;
}
},
error: function (jqXHR, textStatus, errorThrown) {
}, complete: function () {
}
});
return returnData;
},
The problem that I have is that on my main javascript all the functions, including the form validation are executed without waiting for the translation object to get a value.
I need to wait for all my functions until the call to get the translation resources to finish.
Any clue?
You can promisify your 'getTranslations' function and use await where you are calling it.Like this :
getTranslations: function () {
// start ajax request
return new Promise((resolve,reject)=>{
$.ajax({
url: appData.getTranslations,
type: 'POST',
contentType: 'application/json',
dataType: "json",
async: false, // SYNCRONOUS CALL
success: function (data, textStatus, jqXHR) {
if (data.success) {
resolve(data.data);
}
},
error: function (jqXHR, textStatus, errorThrown) {
}, complete: function () {
}
});
});
},
Now await this call in your document.ready() function.
(function (document, window, $) {
'use strict';
var Site = window.Site;
var translations = [];
$(document).ready(async function ($) {
translations = await Site.getTranslations();
//change your immediately invoked functions into named functions
// and call them here
initialisation();
validation();
Site.run(); // glogal site setup
});
// Init function
// ------------------------
function initialisation() {
$("#cbolanguage").change(function (e) {
// start ajax request
$.ajax({
url: url.switchLang,
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ lang: e.target.value }),
dataType: "json",
success: function (data, textStatus, jqXHR) {
if (data.success) {
location.reload();
}
},
error: function (jqXHR, textStatus, errorThrown) {
}, complete: function () {
}
});
});
function init() {
$('#btn-login').click(function (e) {
e.preventDefault();
$('#form-login').data('formValidation').validate();
if (!$('#form-login').data('formValidation').isValid()) return;
});
init();
}
};
// Validataion
// ------------------------
function validation() {
$('#form-login').formValidation({
framework: "bootstrap",
icon: null,
fields: {
Login: {
validators: {
notEmpty: {
message: translations.text1 // NEED TO WAIT UNTIL THIS HAS A VALUE
}
}
},
Password: {
validators: {
notEmpty: {
message: translations.text1 // NEED TO WAIT UNTIL THIS HAS A VALUE
}
}
},
},
err: {
clazz: 'text-help'
},
row: {
invalid: 'has-error'
}
}).on('err.field.fv', function (e, data) {
data.fv.disableSubmitButtons(false);
})
.on('success.field.fv', function (e, data) {
data.fv.disableSubmitButtons(false);
});;
}
})(document, window, jQuery);

using $.when to execute first ajax then execute the next in $.when().done

I know this has been asked multiple times but I'm having a problem executing $.ajax by order using $.when.
In the sample code below, I want to run the first ajax inside $.when() then the second $.ajax inside .done().
var api = {
getFoo: function(callback) {
$.when(this.getBar()).done(function() {
chrome.storage.local.get(['bar'], function(data) {
// omitted some code here for brevity
$.ajax({
type: 'GET',
url: /api/foo/,
dataType: 'json'
}).done(function(result) {
console.log('success', 'went here!');
}).fail(function(request) {
console.log('failed', 'went here!');
});
});
});
},
getBar: function() {
chrome.storage.local.get(['data1'], function(data) {
if(typeof data['data1'] !== 'undefined') {
// omitted some code here for brevity
$.ajax({
type: 'POST',
url: /api/bar/,
data: data['data1'],
dataType: 'json'
}).done(function(result) {
console.log('success', 'went here!');
}).fail(function(xhr, status, error) {
console.log('failed', 'went here!');
});
}
});
}
}
When I ran the code, the second $.ajax execute immediately without waiting for the first $.ajax to finish. Please, could anyone redirect me to the right way?
We need to return a promise for async actions
try this:
getFoo: function(callback) {
this.getBar().then(function(){
chrome.storage.local.get(['bar'], function(data) {
// omitted some code here for brevity
$.ajax({
type: 'GET',
url: /api/foo/,
dataType: 'json'
}).done(function(result) {
console.log('success', 'went here!');
}).fail(function(request) {
console.log('failed', 'went here!');
});
});
});
},
getBar: function() {
var deferred = $q.defer();
chrome.storage.local.get(['data1'], function(data) {
if(typeof data['data1'] !== 'undefined') {
// omitted some code here for brevity
$.ajax({
type: 'POST',
url: /api/bar/,
data: data['data1'],
dataType: 'json'
}).done(function(result) {
deferred.resolve(result);
}).fail(function(xhr, status, error) {
deferred.reject(error);
});
}
});
return deferred.promise;
}
There is a good example at jQuery - when() page. Here is a short example:
var api = {
flag: $.Deferred(),
getFoo: function(callback) {
$.when(this.flag).done(function() {
console.log('getFoo');
});
},
getBar: function() {
console.log('getBar');
this.flag.resolve();
}
}

Double ajax request response

I'm using ajax successives requests and I need do a callback when all the successives requests are done
function doAjaxRequest(data, id) {
// Get payment Token
return $.ajax({
type: "POST",
url: 'exemple1.php',
data: data
success: function(msg){
$.ajax({
type: "POST",
url: 'exemple2.php',
data: msg,
success: function(msgr) {
document.getElementById(id).value=msgr;
},
error:function (xhr, status, error) {
//Do something
}
});
},
error:function (xhr, status, error) {
//Do something
}
});
}
$.when(
doAjaxRequest(data, "input-1"),
doAjaxRequest(otherData, "input-2")
).done(function(a1, a2){
//Need do something when both second ajax requests (example2.php) are finished
}
With this code, the done function is call before my calls to "exemple2.php" are succeeded.
How can I wait for that?
Thanks for answering!
function doAjaxRequest(data, id) {
// Get payment Token
return new Promise(function(resolve,reject){
$.ajax({
type: "POST",
url: 'exemple1.php',
data: data
success: function(msg){
$.ajax({
type: "POST",
url: 'exemple2.php',
data: msg,
success: function(msgr) {
document.getElementById(id).value=msgr;
resolve();
},
error:function (xhr, status, error) {
//Do something
reject();
}
});
},
error:function (xhr, status, error) {
//Do something
reject();
}
});
});
}
Promise.all([
doAjaxRequest(data, "input-1"),
doAjaxRequest(otherData, "input-2")])
.then(function(values){
//Need do something when both second ajax requests (example2.php) are finished
}
Your sub ajax request is independant of the first ajax result, then the call to example2 is completely separated from the $.when() promise.abort
Just try to use the fact that jquery $.ajax return promise like object
Here my code from plnkr
// Code goes here
function doAjaxRequest(data, id) {
// Get payment Token
return $.ajax({
type: "GET",
url: 'example1.json',
data: data
}).then(function(msg, status, jqXhr) {
return $.ajax({
type: "GET",
url: 'example2.json',
data: msg
});
}).done(function(msgr) {
console.log(msgr);
return msgr;
});
}
var data = {foo:'bar'};
var otherData = {foo2:'bar2'};
$.when(
doAjaxRequest(data, "input-1"),
doAjaxRequest(otherData, "input-2")
).done(function(a1, a2) {
console.log(a1, a2);
//Need do something when both second ajax requests (example2.php) are finished
});
Attention, I replace POST by GET and use exampleX.json files for my tests on plnkr
You can test it here : https://plnkr.co/edit/5TcPMUhWJqFkxbZNCboz
Return a custom deferred object, e.g:
function doAjaxRequest(data, id) {
var d = new $.Deferred();
// Get payment Token
$.ajax({
type: "POST",
url: 'exemple1.php',
data: data
success: function(msg){
$.ajax({
type: "POST",
url: 'exemple2.php',
data: msg,
success: function(msgr) {
document.getElementById(id).value=msgr;
d.resolveWith(null, [msgr]); // or maybe d.resolveWith(null, [msg]);
},
error:function (xhr, status, error) {
//Do something
d.reject();
}
});
},
error:function (xhr, status, error) {
//Do something
d.reject();
}
});
return d;
}
Now, i'm not sure what is your expected datas passed to $.when().done() callback.

show() overwritten multiple ajax calls

I have one html element (elem1) and 2 JS functions (func1, func2) that hides and shows elem1 respectively. These JS functions make individual ajax calls and func2 is calling func1 internally.
Problem: I need to call func2, which internally calls func1. Calling func1 hides elem1. After calling func1, I want to show elem1. But this show is not working.
JSFiddle: https://jsfiddle.net/46o93od2/21/
HTML:
<div id="elem">
Save ME
</div>
<br/>
<button onclick="func1()" id="func1">Try Func1</button>
<button onclick="func2()" id="func2">Try Func2</button>
JS:
function func1() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {}, // send in your data
success: function (data) {
//var aData = JSON.parse(data); // there is no data to parse
$('#elem').hide();
},
error: function (xhr, errmsg, err) {
alert('error');
}
});
}
function func2() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {}, // send in your data
success: function (data) {
//var aData = JSON.parse(data); // there is no data to parse
func1();
$('#elem').show();
},
error: function (xhr, errmsg, err) {
alert('error');
}
});
}
Make func1 take a callback function that tells it what to do after it gets the response. func2 can pass a function that shows the element.
function func1(callback) {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {
json: ''
}, // send in your data
success: function(data) {
if (callback) {
callback();
} else {
$('#elem').hide();
}
},
error: function(xhr, errmsg, err) {
alert('error');
}
});
}
function func2() {
$.ajax({
url: '/echo/json/', //use the correct processing url here
type: "POST",
data: {
json: ''
}, // send in your data
success: function(data) {
func1(function() {
$('#elem').show();
});
},
error: function(xhr, errmsg, err) {
alert('error');
}
});
}
DEMO

Categories