Trying to postpone further processing of script until ajax call is complete without using the callback. Trying something like this, but it locks. How do I do this without locking?
var loaded=false;
$.get(url,function(d){loaded=true;});
while(!loaded) //<--locks here
setTimeout(void(0),100);
//continue script after ajax call is complete
Have you tried with promises?
var jqxhr = $.get( url, function() {
alert( "success" );
})
.done(function() {
void(0);
})
.fail(function() {
void(0);
})
.always(function() {
alert( "finished" );
});
Try this
var loaded=false;
$.ajax({
url : 'your url',
type : 'GET',
async : false, // You need this
complete: function(data) {
loaded=true;
},
});
while(!loaded) //<--locks here
setTimeout(void(0),100);
If you work with jQuery, deferred objects are the way to go. They implement a robust and easy methodology.
However, if you want your script to work, try this:
var loaded = false;
function myfunc() {
if (loaded) {
clearInterval(timeout);
doSomethingAfter();
}
}
var timeout = setInterval(myfunc, 100);
$.get(url,function(d){loaded=true;});
Related
I am working on a web application for debtor management and I am refactoring the code and try to adhere to the principle of separation of concerns. But the async nature of AJAX is giving me headaches.
From a jQuery dialog the user can set a flag for a debtor which is then stored in a database. If that succeeds, the dialog shows a notification. Until now I handled everything inside the jQuery Ajax success callback function: validating input, doing the ajax request and updating the content of the dialog.
Of course this lead to spaghetti code.
Thus I created a class AjaxHandler with a static method for setting the flag, which is invoked by the dialog. I thought that the dialog could update itself according the the return value of the AjaxHandler but I did not have the asynchronity in mind.
The following question was helpful in tackling the return values.
How do I return the response from an asynchronous call?
But how can I update the dialog without violating the SoC principle?
EDIT
$("#button").on("click", function() {
var returnValue = AjaxHandler.setFlag();
if(returnValue) { $("#div").html("Flag set"); }
else { $('#div").html("Error setting flag");
});
class AjaxHandler {
static setFlag(){
$.ajax({
type: "POST",
url: "ajax/set_flag.php",
success: function(returndata){
return returndata; //I know this does not work because of
//ASYNC,but that is not the main point.
}
}
})
There is many ways to handle async responses, but the jQuery way is slightly different, so when you are already using jQuery, handle it this way:
$('#button').on('click', AjaxHandler.setFlag)
class AjaxHandler {
static setFlag () {
this.loading = true
this
.asyncReq('ajax/set_flag.php')
.done(function () {
$('#div').html('Flag set')
})
.fail(function (err) {
$('#div').html('Error setting flag. Reason: ' + err)
})
.always(function () {
this.loading = false
})
}
asyncReq (url) {
return $.ajax({
type: 'POST',
url: url
})
}
})
Consider using events perhaps here?
$("#button").on("click", function() {
$('body').trigger('getdata', ["", $('#div')]);
});
$('body').on('getdata', function(event, datasent, myelement) {
var attach = event.delegateTarget;// the body here
var getAjax = $.ajax({
type: "POST",
url: "ajax/set_flag.php",
data: datasent // in case you need to send something
})
.done(function(data) {
$(attach).trigger('gotdata', [data, myelement]);
});
getAjax.fail(function() {});
})
.on('gotdata', function(event, datathing, myelement) {
myelement.html(!!datathing ? "Flag set", "Error setting flag");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
Note that inside those event handlers you could also call some function, pass a namespace for the function, basically do it as you please for your design.
I can display the message using javascript/jquery and i have ajax request but that message is not disappearing after some seconds and i want to disappear it.
My Code
$('#password_change_form').submit(function(e) {
e.preventDefault();
var saveThis = $(this);
$.ajax({
type: "POST",
url: "/changepassword",
data: $(saveThis).serialize(),
success: function(data) {
$(".success-messages").text("Heslo bylo úspešne zmeneno").fadeIn();
setTimeOut(function(){
$(".success-messages").fadeOut('slow');
},2000);
$('#password_change_form').trigger("reset");
},
error: function (data) {
$(".error-messages").text("Zadali jste špatné heslo").fadeIn();
setTimeOut(function(){
$(".error-messages").fadeOut('slow');
},2000);
$('#password_change_form').trigger("reset");
}
});
}),
I have setup a setTimeOut function but its not working i dont kno where is the issue:
Your help needs here!
Aside from the already pointed out simple typo, jQuery has its own delay() function, simply use: $(".success-messages").delay(2000).fadeOut('slow')
You may not need the setTimeout since jquery provides fadeOut which have a signature like this
$(selector).fadeOut(speed,easing,callback)
In the speed you can either provide time in millisecond or slow or fast
$(".success-messages").fadeOut(2000);
setTimeOut should be setTimeout. Thats All.
Could also use:
$(document).ready(function(){
$(".foo_msg").fadeTo(2000, 500).slideUp(500, function(){
$(".foo_msg").slideUp(600);
});
})
mess around with the values to get desired time
also include "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js" in your script tag
There's a typo in your code:
setTimeOut(function(){
$(".success-messages").fadeOut('slow');
},2000);
It should be:
setTimeout(function() {
$(".success-messages").fadeOut('slow');
}, 2000);
you can always make use of the Mozilla Developer Network (MDN) JS-reference for looking up details about syntax:
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
You can use JQuery delay() and i will do something like this in your case:
$('#password_change_form').submit(function(e)
{
e.preventDefault();
var saveThis = $(this);
$.ajax({
type: "POST",
url: "/changepassword",
data: $(saveThis).serialize(),
success: function(data)
{
var msg = "Heslo bylo úspešne zmeneno";
$(".success-messages").text(msg).fadeIn().delay(2000).fadeOut("slow");
$('#password_change_form').trigger("reset");
},
error: function (data)
{
var msg = "Zadali jste špatné heslo";
$(".error-messages").text(msg).fadeIn().delay(2000).fadeOut("slow");
$('#password_change_form').trigger("reset");
}
});
});
I have a project which involves live notification. So I stumbled upon using socket io but I didn't have enough time to learn it yet. So I tried doing it with AJAX and jQuery. Below is my code structure and I was wondering if this is gonna work with no drawbacks?
setInterval(function(){
if( !element.hasClass('processing') ){
element.addClass('processing');
$.ajax({
type: 'post',
dataType: 'json',
url: ajaxurl,
data: {},
success: function( response ){
/* Success! */
element.removeClass('processing');
}
});
}
}, 2500);
Some Extra Info
The way you described will work. From Experience I would just like to point out some things.
I usually do a recursive function, allows you to wait your interval between ajax calls and not a fixed rate. //OPTIONAL BUT DOES GIVE THE SERVER SOME BREATHING ROOM.
Use window.setTimeout() with an isActive flag. //ALLOWS YOU TO STOP POLLING FOR WHATEVER REASON, AND BECAUSE FUNCTION IS RECURSIVE START UP AGAIN IF NEED BE
For Sake of being thorough, I found it is always a good idea to handle the error case of the $.ajax() post. You could perhaps display some message telling the user he is no longer connected to the internet etc.
Some Sample Code:
var isActive = true;
$().ready(function () {
//EITHER USE A GLOBAL VAR OR PLACE VAR IN HIDDEN FIELD
//IF FOR WHATEVER REASON YOU WANT TO STOP POLLING
pollServer();
});
function pollServer()
{
if (isActive)
{
window.setTimeout(function () {
$.ajax({
url: "...",
type: "POST",
success: function (result) {
//SUCCESS LOGIC
pollServer();
},
error: function () {
//ERROR HANDLING
pollServer();
}});
}, 2500);
}
}
NOTE
This is just some things I picked up using the exact method you are using, It seems that Web Sockets could be the better option and I will be diving into that in the near future.
Please refer :
Jquery : Ajax : How can I show loading dialog before start and close after close?
I hope this could help you
$("div.add_post a").click(function(){
var dlg = loadingDialog({modal : true, minHeight : 80, show : true});
dlg.dialog("show");
$.ajax({
url : "/add.php",
complete : function (){
dlg.dialog("hide");
}
});
return false;
});
//--Loading dialog
function loadingDialog(dOpts, text = "пожалуйста подождите, идет загрузка...")
{
var dlg = $("<div><img src='/theme/style/imgs/busy.gif' alt='загрузка'/> "+text+"<div>").dialog(dOpts);
$(".ui-dialog-titlebar").hide();
return dialog;
}
I am using JQuery when. The syntax looks like this:
$.when(
// Get the HTML
$.get("/feature/", function(html) {
globalStore.html = html;
}),
// Get the CSS
$.get("/assets/feature.css", function(css) {
globalStore.css = css;
}),
// Get the JS
$.getScript("/assets/feature.js")
).then(function() {
// Add CSS to page
$("<style />").html(globalStore.css).appendTo("head");
// Add HTML to page
$("body").append(globalStore.html);
});
My question
How can I do error handling when one of the call to the server results in exception (failure scenario) or error handling for any other scenario?
Since I am making Ajax request here, how can I define timeout period for the Ajax request?
deferred.then( doneCallbacks, failCallbacks ) can take a failure filter like
$.when(
// Get the HTML
$.get("/feature/", function(html) {
globalStore.html = html;
}),
// Get the CSS
$.get("/assets/feature.css", function(css) {
globalStore.css = css;
}),
// Get the JS
$.getScript("/assets/feature.js")
).then(function() {
// Add CSS to page
$("<style />").html(globalStore.css).appendTo("head");
// Add HTML to page
$("body").append(globalStore.html);
}, function(){
//there is an exception in the request
});
To setup the timeout, you can use the timeout option.
You can use it either globally like
jQuery.ajaxSetup({
timeout: 5000
})
or use $.ajax() instead of the short version $.get() with the timeout option
I think it is because the calls are async. When using:
$.ajax({
url: "file.php",
type: "POST",
async: false,
success: function(data) {
}
});
The call is synchronous.
I want to execute a piece of javascript after the ajax response has been rendered. The javascript function is being generated dynamically during the ajax request, and is in the ajax response. 'complete' and 'success' events to not do the job. I inspected the ajax request in Firebug console and response hasn't been rendered when the complete callback executes.
Does not work:
function reloadForm() {
jQuery.ajax({
url: "<generate_form_url>",
type: "GET",
complete: custom_function_with_js_in_response()
});
};
ajaxComplete does the job, but it executes for all the ajax calls on the page. I want to avoid that. Is there a possible solution?
$('#link_form').ajaxComplete(function() {
custom_function_with_js_in_response();
});
you can also use $.ajax(..).done( do_things_here() );
$(document).ready(function() {
$('#obj').click(function() {
$.ajax({
url: "<url>"
}).done(function() {
do_something_here();
});
});
});
or is there another way
$(document).ready(function() {
$('#obj').click(function() {
$.ajax({
url: "<url>",
success: function(data){
do_something_with(data);
}
})
});
});
Please, utilize this engine for share your problem and try solutions. Its very efficient.
http://jsfiddle.net/qTDAv/7/ (PS: this contains a sample to try)
Hope to help
Checking (and deferring call if needed) and executing the existence of the callback function might work:
// undefine the function before the AJAX call
// replace myFunc with the name of the function to be executed on complete()
myFunc = null;
$.ajax({
...
complete: function() {
runCompleteCallback(myFunc);
},
...
});
function runCompleteCallback(_func) {
if(typeof _func == 'function') {
return _func();
}
setTimeout(function() {
runCompleteCallback(_func);
}, 100);
}
Can't help a lot without code. As an general example from JQuery ajax complete page
$('.log').ajaxComplete(function(e, xhr, settings) {
if (settings.url == 'ajax/test.html') {
$(this).text('Triggered ajaxComplete handler. The result is ' +
xhr.responseHTML);
}
});
In ajaxComplete, you can put decisions to filter the URL for which you want to write code.
Try to specify function name without () in ajax options:
function reloadForm() {
jQuery.ajax({
url: "<generate_form_url>",
type: "GET",
complete: custom_function_with_js_in_response
});
};