Loader-GIF doesn't move when AJAX is loading - javascript

I'm trying to make a GIF-loader, which will be shown as long as my AJAX request is being processed. I'm using the jquery loader plugin.
The problem is, the GIF doesn't move when the browser is busy processing the AJAX request, though it is moving, when setting it to visible for testing purposes.
I've tested it in 3 major browsers.
This is an extract of my code. The real code is, of course, much more complex:
$("#myButton").click(function() {
$.loader({
className: "blue-with-image-2",
content: ''
});
getData();
});
function getData() {
$.ajax({
type: "GET",
url: "https://jsonplaceholder.typicode.com/photos",
success: function(data) {
// do something with data
console.log(data)
$.loader('close'); // close the loader
},
error: function(jqXHR, status, error) {
console.error(status, error);
}
});
}
Here is a fiddle with that example code.
The funny thing is, when testing this particular code in jsFiddle, it does
work. But not my real code, which is almost the same, but just more complex.

Use function 'beforeSend' in ajax call
function getData() {
$.ajax({
type: "GET",
url: "https://jsonplaceholder.typicode.com/photos",
beforeSend: function() {
$('#response').html("<img src='/images/loading.gif' />");
},
success: function(data) {
// do something with data
console.log(data)
$.loader('close'); // close the loader
},
error: function(jqXHR, status, error) {
console.error(status, error);
}
});

Related

ajax, error is called but it work anyway

I send a post request using ajax, the data is being saved in the database but my success function never run?
If I put the success function in the error function the app is behaving as I would expect. I dont see any error messages in the node terminal. I have built the API myself, but I have noticed any problems before.
I am still on the steep learning curve, is there something wrong I have missed in my code?
$('#newPoiForm').on('submit', function(e) {
e.preventDefault();
let formData = $(this).serialize();
$.ajax({
dataType: 'json',
type: 'POST',
url: '/api/pois/',
data: formData,
success: function(message) {
console.log('success, now run the success function');
// add the new point ajax should go here
},
error: function(data) {
console.log('something went wrong');
$.ajax({
dataType: 'json',
url: 'http://localhost:3000/api/pois/last',
success: function (data) {
$(data.features).each(function (key, data) {
// add last to poi
console.log('last point added');
poi.addData(data);
});
}
});
}
});
first get rid of the nested success function within the error function and replace the error function with this to debug the cause:
error: function(ts) { alert(ts.responseText) }
Then have a look at the url, they differ within your success functions.
Either simply the first url-parameter is wrong, or the response is invalid.

Writing a jQuery AJAX request using a plain JS promise

I am currently moving my webpage over to a SPA (single page application) and in doing so I am now working with only one html page, which gets populated using JS (as a normal SPA should do). As such, that means (for convenience sake) I am cutting down my JS files to one (maybe a good idea, maybe a bad one - we'll see, but that's not the point). I have decided to make a "black box" AJAX request handler, so as to minimize code. This is where I ran into a problem I was not expecting. The code is (the example click is for my login screen):
function ajaxCall(type, url, data, dataType) {
$.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
})
.done(function(xhr) {
return xhr;
})
.fail(function(xhr, status, errorThrown) {
console.log('AJAX call error: ' + errorThrown);
console.dir(xhr);
})
.always(function(xhr, status) {
console.log('AJAX call status: ' + status);
});
}
var res;
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
console.log('res =', res); // this is where the problem was discovered
});
(some of you are already groaning) Of course, when I tested this, what I got in my console is res = undefined.
I have spent hours researching this problem, and have figured out why it happens. These are some of the pages I researched in trying to solve this: 1 2 3
To cut to the chase: The problem is that I am not using a Promise. I got that. I can fix that. What I cannot seem to fix is using a plain JS Promise with a jQuery AJAX request.
I have gotten this far:
function ajaxCall(type, url, data, dataType) {
return Promise.resolve($.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
}));
}
but I cannot figure out how to incorporate the other features/functions of a promise, which are: .then() and .reject(). As far as I understand, the above Promise will automatically resolve, but what if it needs to be rejected? Maybe I am still thinking with jQuery's .done(), .fail() and .always().
But for the life of me, despite all the Googling I do, I cannot find how to fully incorporate all the functions of a plain JS Promise with a jQuery AJAX request.
Thus, I am asking the stackoverflow community for insight into this problem.
Thank you.
So Promise isn't really your savior here. The issue you have is that you need to call the console.log('res =', res); after the AJAX request is done using the .done() and .fail() methods.
function ajaxCall(type, url, data, dataType) {
return $.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
});
}
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
var res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
res.done(function (data) {
console.log('res =', data);
});
});
If you really want to use a real Promise, you can do something like
function ajaxCall(type, url, data, dataType) {
return new Promise(function (resolve, reject) {
$.ajax({
type: type,
url: url,
data: data,
dataType: dataType,
}).done(function (data) {
resolve(data);
}).fail(function (jqXHR, textStatus, errorThrown) {
reject(errorThrown);
});
});
}
//this is inside $(document).ready - I just skipped some lines
$(document).on('click', '#submit', function(e) {
var res = ajaxCall('POST', '/Login', { 'username': $('#username').val(), 'password': $('#password').val() }, 'json');
res.then(function (data) {
console.log('res = ', data);
}).catch(function (err) {
console.error(err);
});
});

How to transform $.post to $.ajax?

I have this $.post peace of code:
$.post("../admin-login",
{
dataName:JSON.stringify({
username:uname,
password:pass,
})
}, function(data,status){
console.log("Data:"+data);
answer = data;
}
);
and I wont to transform it to $.ajax. On the servlet side I am demanding request.getParamter("dataName") but I do not know how to write data: section in $.ajax so that I can get parameters like that(request.getParamter("dataName"))? Also, it seems to be problem with this type of code, I am asuming cause of async, that I cannot do this:
var answer="";
function(data,status){
console.log("Data:"+data);
answer = data;
}
And that answer is keeping empty(""), even though in console is written in deed "true" or "false" as my server answers. What is this about?
Thanks in advance.
I found out that problem is in the click() event. Ajax finishes when click() finishes, so I am not able to get data before event is done. What is bad in that is that I cannot fetch data because it is finished. Does anyone know how to solve this?
$.post("../admin-login",
{
dataName:JSON.stringify({
username:uname,
password:pass,
})
}, function(data,status){
console.log("Data:"+data);
answer = data;
}
);
becomes
function getResult(data) {
// do something with data
// you can result = data here
return data;
}
$.ajax({
url: "../admin-login",
type: 'post',
contentType: "application/x-www-form-urlencoded",
data: {
dataName:JSON.stringify({
username:uname,
password:pass,
})
},
success: function (data, status) {
getResult(data);
console.log(data);
console.log(status);
},
error: function (xhr, desc, err) {
console.log(xhr);
}
});
You need to see how the information os arriving to your servlet as query parameter or payload.
See this HttpServletRequest get JSON POST data
You could try structuring your AJAX request like the below:
var dataName = username:uname, password:pass;
$.ajax({
url: "../admin-login",
data: JSON.stringify(dataName),
type: "POST",
cache: false,
dataType: "json"
}).done(function(data, status) {
console.log("Data:"+data);
answer = data;
});

Is there a way to add an OnSuccess script to my Ajax call

I have the following script:
$.ajax({
url: '/Switch/showOptions',
data: {
switchid: "331",
},
type: 'get',
success: function (html) {
$('#showoptions').html(html);
$("#showoptions").dialog("show"); //This could also be dialog("open") depending on the version of jquery ui.
OnSuccess('createsuccess')
},
});
What I am trying to do is to fire an OnSuccess script after showing the dialog, currently I am getting an exception that OnSuccess is not defined? So can anyone advice how I can fire an OnSuccess script for my Ajax call?
Try this using jQuery.when() as described in this answer here:
Provides a way to execute callback functions based on one or more
objects, usually Deferred objects that represent asynchronous events.
So with that in mind, here is your code reworked to use jQuery.when():
var ajax_action = $.ajax({
url: '/Switch/showOptions',
data: {
switchid: "331",
},
type: 'get',
success: function (html) {
$('#showoptions').html(html);
$("#showoptions").dialog("show"); //This could also be dialog("open") depending on the version of jquery ui.
},
});
$.when(ajax_action).then(function(data, textStatus, jqXHR) { OnSuccess('createsuccess'); });
Or if you just want to test this concept, change the jQuery.when() to be this:
$.when(ajax_action).then(function(data, textStatus, jqXHR) { alert('I am a success!'); });
EDIT: Last edit to try and address original posters request. They want to fire a script called createsuccess, so just do this:
$.when(ajax_action).then(function(data, textStatus, jqXHR) { createsuccess(); });
Your code should work if you add a ; after your OnSuccess call. This isn't an event to be fired but it is a a function that will be executed after the first two statements.
function OnSuccess(p_Success) {
alert('it worked!');
}
$.ajax({
url: '/Switch/showOptions',
data: {
switchid: "331",
},
type: 'get',
success: function (html) {
$('#showoptions').html(html);
$("#showoptions").dialog("show"); //This could also be dialog("open") depending on the version of jquery ui.
OnSuccess('createsuccess');
},
});

Show a loading div during ajax post

I have a mobile app using mostly JQuery Mobile. I have an ajax function using POST and I can't seem to get anything to effect the UI when I fire the click event. I tried setting
$('#cover').show();
as the very first thing in the function then I do some basic things like document.getElementById('user') etc to set some variables and check input, but as long as the ajax function is there it won't show the div or even the spinner from JQ Mobile. Unless I debug and step through the code then the spinner and div show up fine. I tried setTimeout and putting it in the beforeSend area of the ajax call. Everything works fine otherwise. It seemed to work a little better with GET I'm not sure if that has anything to do with it or not.
$.ajax({
cache: false,
type: "POST",
async: false,
url: urlString,
data: jsonstring,
contentType: "application/json",
dataType: "json",
success: function (data) {
JSONobj = JSON.parse(data);
},
beforeSend: function(xhr){
//console.log('BeforeSend');
},
complete: function (xhr) {
//console.log('Complete');
},
error: function (xhr, status, error) {
console.log(error);
}
});
You could use the Ajax Global handlers to handle this:
$(document).
.ajaxStart(function(){
$('#cover').show();
})
.ajaxStop(function(){
$('#cover').hide();
});
This way you don't have to worry about showing/hiding the overlay on individual Ajax calls.
Try this
$("#someButton").click(function(e){
e.preventDefault() //if you want to prevent default action
$('#cover').fadeIn(100,function(){
$.ajax({
url: "someurl",
data: "Somedata",
contentType: "application/json",
dataType: "json",
},
success: function (data) {
JSONobj = JSON.parse(data);
$('#cover').fadeOut(100);
},
complete: function (xhr) {
$('#cover').fadeOut(100);
}
});
});
});

Categories