jQuery AJAX call initiates without command when .done function added - javascript

I'm rewriting a series of jQuery AJAX requests and have been having trouble with .done code blocks. I'm attempting to send an AJAX request and wait for the response before processing the data. As a guide, I have been using the following page:
http://michaelsoriano.com/working-with-jquerys-ajax-promises-and-deferred-objects/
I've also looked at countless stack questions to try and troubleshoot my issues, but haven't found anything which has helped. For reference, some of the questions I've looked at are below:
jQuery Ajax call not processing .done
jquery ajax done function not firing
Confused on jquery .ajax .done() function
I've noticed that when I create code blocks which are similar to the guide above, the functions run on page load, rather than when they are triggered in code. To isolate the fault, I created a simple example, as below:
<!DOCTYPE html>
<html lang="en">
<body>
<button type="button" onclick="getData()">Click me</button>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
//Commented out due comment below
/*function getData() {
console.log('enter getData');
return $.ajax({url:'./testajax.html',type:"POST"});
}
getData().done(function(data){
console.log('enter done');
alert(data);
});*/
function getData() {
console.log('enter getData');
$.ajax({ url: './testajax.html', type: "POST" })
.done(function (data) {
console.log('enter done');
alert(data);
});
alert('after');
}
</script>
</html>
I was expecting that when my example page loaded, nothing would happen, as there was no trigger to execute the getData() function unless the button was clicked. However, when I load the page, my console logs 'enter getData' and then 'enter done', and I get an alert with the contents of my ./testajax.html page (just a single string). Further, when I then click the button, it enters getData() but doesn't trigger the getData().done function, so no alert is received.
Is anyone able to guide me on the right track here and help me prevent the getData() function from executing on page load, and instead make the button click execute the AJAX request, wait for the result, then execute the code in the .done block?

The getData() expression you have immediately calls the function on pageload. Then you attach a .done handler to it.
It sounds like you want a function that calls $.ajax and attaches .done to it, like:
function getData() {
console.log('enter getData');
$.ajax({ url: './testajax.html', type: "POST" })
.done(function (data) {
console.log('enter done');
alert(data);
});
}
Then attach getData as an event handler somewhere.
Don't use inline handlers. Use .addEventListener or jQuery's .on('click' instead.

Related

WickedPDF and JS

I am trying to execute some ajax requests in the pdf.html file for a ruby app using WickedPDF. I have the javascript outputting some append statements to keep track of the functions reached.
The first ajax call is successful, as I have outputted the json result in the pdf file. However, in that same success call, I call another function, which for now, I only have it outputting an append statement to indicate it is being executed. However, it does not happen. Any ideas?
HTML:
<div id="data"></div>
Javascript:
<script>
function getData(data) {
$('div#data').append('<p>getData function called</p>');
}
</script>
<script>
$(function() {
var assays = '';
$.ajax({
type: 'GET',
url: 'http://www.url.com/data.json'
})
.done(function(result) {
$('div#data').append('<p>First ajax call called!</p>');
data = result['DataList']['list'];
getData(data);
})
.fail(function() {
$('div#data').append('<p class="center">Data is unavailable.</p>');
});
});
</script>
Thanks for your help.
wkhtmltopdf will by default stop slow running JavaScripts if they are delaying rendering.
Try experimenting with the following options: --no-stop-slow-scripts, --javascript-delay <msec>
More options are listed here

How to unblock a blocked page with jquery-blockui?

I start to using jQuery BlockUI Plugin to block user activity for the page until complete a button process on C#/ASP.NET side.
So I wrote this;
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<script src="http://malsup.github.io/min/jquery.blockUI.min.js" ></script>
<script type="text/javascript">
$(document).ready(function () {
$('#MyButtonID').click(function () {
$.blockUI({ message: '<h1>Please wait..</h1>' });
});
});
</script>
As you can see, this is a simple code that blocks UI when I click asp:button which ID is MyButtonID until it finish it's process. This works great.
Now I try to create some alert based on a condition while on this click process. If I understand clearly, now I need to unblock my page as a first, show the alert and keep it blocked again until complete button process.
That's why I wrote two function (maybe I can call these $.unblockUI and $.blockUI directly without them?) in my javascript side for that;
function UnblockUI() {
$.unblockUI();
}
function BlockUI() {
$.blockUI({ message: '<h1>Please wait..</h1>' });
}
As far as I search, most common way to call Javascript function on server side is using ClientScriptManager.RegisterStartupScript method in C#. So I tried to alert something on C# side as an example with;
if(condition)
{
string script = string.Format("alert('{0}');", "Some error message");
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "alert", script, true);
}
and it worked. After that, I tried to unblock page with calling UnblockUI function in my javascript side but it didn't unblock it.
if(condition)
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "unblock", "UnblockUI", true);
string script = string.Format("alert('{0}');", "Some error message");
Page.ClientScript.RegisterClientScriptBlock(Page.GetType(), "alert", script, true);
}
If I understand correctly, this UnblockUI parameter calls my UnblockUI javascript function which I defined above and this function calls $.unblockUI(); and unblock my page which is blocked but as expected, it didn't work.
What am I missing here? Or am I didn't even understand that This plugin lets you simulate synchronous behavior when using AJAX, without locking the browser sentence?
Try using the function call as follows:
function unblockUI() {
$(function() {
$.unblockUI();
});
}
function blockUI() {
$(function() {
$.blockUI({ message: '<h1>Please wait..</h1>' });
});
}
I hope I have helped...
Here is what i am using in my current project.
$(document).ready(function () {
// unblock when ajax activity stops when DOM gets updated, means Ajax is completed
$(document).ajaxStop($.unblockUI);
//Block when trying for Ajax Activity
$('ul#Appdropdown').click(function (ev) {
$.blockUI();
//Add ajax call to get data
}
});
Implement the same and it will do the block and unblock for you.
I had an issue when using the $ajax complete function to stop the animation, If the ajax call fails i was resubmitting the ajax call, and wanted to block UI on resubmitting. But when making the call $.unblockUI inside of complete it was not animating correctly. It would flicker and disapear and not continue to block. However using global call to stop did work, allowing for blocking to re occur with a updated message on blocked UI.
$(document).ajaxStop($.unblockUI); // this works
instead of inside of the complete function of ajax
$.ajax({
complete: function(jqXHR, textStatus) {
$.unblockUI();// this did not always work
}
});
If you block user interface on this way :
BlockUI.Component(".page-content");
Then this is a working solution:
BlockUI.UnblockComponent(".page-content");

ajaxSuccess event firing sequence

as a debugging/learning tool I insert this into my code:
$(document).ajaxSuccess(function() {
console.log('ajax complete');
});
I want to see where ajax gets its answer related to other events using console.log().
So I have:
function place_confirm (place_name,place_code) {
console.log('into place_confirm');
var place_confirm_html= '<p>confermi da '+place_name+ '?</p>';
//here the function does other stuff
}
$.post('./shyne/ajax/approve.php', {place_code:place_code}, function (data){
if (data == '_no_'){$('.error').html('il codice non è corretto');
} else {
place_confirm(data,place_code);
}
The strange thing to me is that the console.log writes:
into place confirm
ajax complete
while I thought it had to be the inverse: after ajax complete I have my function associated in success run.
So I have two questions:
does the console give a good representation of the sequence of events happening?
which is the right ajax event to attach a function I want to be executed only after Ajax got its response?
The function place_confirm will be triggered before the ajaxSuccess because the Ajax call is async. So while the JavaScrpt file is waiting for the Ajax Response it will perform other functions. That's why the function will be executed first.
If you want that the ajaxSuccess function will be executed first you need to set the async to false like below:
$.ajax({
async: false,
....
})
.done(function(response){
//Some Logic here if the Ajax succeded
})
.fail(function(jqXHR, textStatus, errorThrown){
alert('Error : ' + errorThrown); // error handling
});
But notice: If you set async to false Javascript MUST NOT perform other code until the AjaxResponse arrived! It will work like a singlethreated programming language!
Btw the code above is the new way to handle Ajax Calls correctly, the old way with Success und Error is deprecated in newer Versions, just for your information :)
The console can give you good information, but it only does so much. The console.log() can't give you information about WHY the functions are called in the order they are executed, but you'll see that they ARE executed in the order. The reason for that behaivior is explained in the first sentence, if you want further information just ask. :)
Sorry for possible bad grammar!
EDIT:
Welcome to stack overflow :)
From what I know the $.post function takes these parameters (URL, dataToPass, successFunction). So what you're doing is calling place_confirm function on success which will be called first before the other ajaxSuccess function you used. So to answer your questions:
1. Yes the sequence is correct.
2. You could use the done() event.
$.post('./shyne/ajax/approve.php', {place_code:place_code})
.done( function (data){
if (data == '_no_'){
$('.error').html('il codice non è corretto');
} else {
place_confirm(data,place_code);
}
})

document.ready() just running one function instead of two

I'm trying to run two js functions(i'm using jquery) in the document.ready(), but only runs one. Here is my code:
$(document).ready(function() {
show_properties();
table_events();
});
the functions are written in the same js file, but only show_properties() is loaded when the website loads. I tested in the firebug console to write
table_events()
and the console tells me "undefined", but after that the function gets loaded and the ajax calls and everything inside that function starts to work.
Why is that? How can I fix this behavior?
thanks.
Here are the functions I want to run:
function table_events(){
$.ajaxSetup ({
cache: false
});
var wait = "<img src='../images/loading_red_transparent.gif' alt='loading...' style='display:block;margin-left:auto;margin-right:auto;'/>";
$('.apartamentos tr').on('click', function() {
alert("hola.")
var id_propiedad = $(this).find(".id_propiedad").html();
var nombre_propiedad = $(this).find(".nombre_propiedad").html();
//$('#property_information').hide('slow');
$("#property_information")
.html(wait)
.load('properties_info.php',{'nombre_propiedad':nombre_propiedad,'id_propiedad':id_propiedad});
//$('#property_information').show('slow');
});
}
function show_properties(){
$.ajaxSetup ({
cache: false
});
var wait = "<img src='../images/loading_red_transparent.gif' alt='loading...' style='display:block;margin-left:auto;margin-right:auto;'/>";
$('#busca_propiedades').on('click',function(){
var user_id = $('#user_list').val();
/*var data = $.ajax({
url: "properties_list.php",
type: 'POST',
data:{ 'user_id': user_id },
cache: false,
async: false
}).responseText;
});*/
$('#lista_aptos')
.html(wait)
.load('properties_list.php',{'user_id':user_id});
//alert(data);
});
}
EDIT:
after some debugging with console.log , i found out that this code is the one that's not executing when the webpage loads:
$('.apartamentos tr').on('click', function() {
alert("hola.")
var id_propiedad = $(this).find(".id_propiedad").html();
var nombre_propiedad = $(this).find(".nombre_propiedad").html();
//$('#property_information').hide('slow');
$("#property_information")
.html(wait)
.load('properties_info.php',{'nombre_propiedad':nombre_propiedad,'id_propiedad':id_propiedad});
//$('#property_information').show('slow');
});
apparently, this function() is the one that doesn't run when the webpage loads; but when I write again in the console
table_events()
THEN the code inside this function runs when I click in the tr of the table.
Are $('.apartamentos tr') elements loaded with the load call in show_properties?
If yes then the problem is due to the fact that when table_events is executed, tr elements are not yet inserted in the #lista_aptos (cause load uses ajax, that's asynchronous).
To check please add
console.log("trs count: ", $('.apartamentos tr').size());
on top of your table_events function.
To fix you should pass table_events as completetion handler to load call:
$('#lista_aptos')
.html(wait)
.load('properties_list.php',{'user_id':user_id}, table_events);
Old response
You said "...after that the function gets loaded and the ajax calls..."
Keep in mind that ajax calls are asynchronous.
If you define the table_events function inside the ajax response handler, also if you do something to put it in a scope visible from the referencing function, the attempt to call table_events may occur before the table_events definition.
or, as Raghavan says, there's an error thrown from show_properties that prevents the execution of table_events. But better if you try to debug with console.log("text") instead of alert (alert is blocking and it will hide you problems from asynchronous calls)
please, try to make a example on http://jsfiddle.net/
If the console returns "undefined" that means the function exists, but it's returning undefined as a result.
Your function needs fixing, $(document).ready() is probably fine.
Try calling table_events() at the last line in show_properties() and see if that works.
A few things to check:
Does table_events exist in the scope of $(document).ready?
Is show_properties possibly raising an error?
This may be a good case for "alert debugging":
$(document).ready(function() {
show_properties();
// You might also put an alert at the very end of show_properties.
alert('show_properties called; now calling table_events()');
table_events();
alert('table_events called; document.ready done');
});
There is probably an error in the table_events function. Try debugging using simple alert statements.

How to Select Text in an Element (akin to highlighting with your mouse) on newly created ajax content?

I'm using the selectText function from here https://stackoverflow.com/a/987376/784637
However when I called this function immediately after an ajax request on the newly created element:
selectText('some-newly-added-element')
I get the following error in firebug
NS_ERROR_DOM_NOT_OBJECT_ERR: Parameter is not an object
[Break On This Error]
range.selectNodeContents(text);
Note that I am able to call this function after the ajax request on the same element like so
$('#container').on('click', '#some-newly-added-element', function(){
selectText('some-newly-added-element');
});
Is there a way to call this function immediately after the ajax request is done?
Re: Is there a way to call this function immediately after the ajax request is done?
Do you mean after success of the ajax success. or http://api.jquery.com/jQuery.ajax/
or This should help: Execute function after all ajax .load() requests are finished
Hope this fits the cause :)
Sample
$.ajax({
url: this.html_url,
cache: false,
success: function(html){
doSomething();
return true;
}
});
use complete callback which will trigger after ajax call
$.ajax({
complete: function(){
selectText('some-newly-added-element');
}
});
Documentation for ajax event: http://docs.jquery.com/Ajax_Events

Categories

Resources