I am working in jQuery and I have a variable that I declared as global in one function and when I alert it it gives me right result but now I want to access the same variable in another function and alert it in another function it gives me empty result mean I cannot access it over there. I know about the scope of a variable but to overcome it I decleared variable as global but I am still unable to access it.
Here is my first function:
var employee_email = '';
function showCustomer()
{
// fire off the request to ajax_stufflist.php
request = $.ajax({
url: "ajax_stufflist.php?"+url,
type: "post",
success: function(data){
if(data != ''){
var response = $(data).find("#gmp_stuff").html();
employee_email = $(data).find(".EMP_EMAIL>span").html();
//alert(employee_email);
$("#user_responses").html(response);
$(function() {
$("#user_responses").dialog({
dialogClass:'transparent',
resizable: false,
draggable: false,
modal: true,
width: 1000,
autoOpen: false,
overlay: { opacity: 0 }
});
$('#user_responses').dialog('open');
$('#user_responses').css('display','');
});
}
},
error:function(){
alert("failure");
$("#user_responses").html('error occured');
}
});
}
In this function the variable employee_email is decleared above the function and I want to access the same variable with value in other function just next to it in same script tag.
function sendEmail(){
alert(employee_email );
request = $.ajax({
url: "send_email.php?"+employee_email ,
type: "post",
success: function(data){
$("#email_responses").html();
},
error:function(){
alert("failure");
$("#email_responses").html('error occured');
}
});
}
Kindly tell me what's wrong with it. Thanks in advance for any kind of help.
This is not a problem of scope. If it would have been, you would have got an error in your console. But you are getting an empty result because either the AJAX call is not complete yet or it has not been able to change the value due to some error there. Try this.
Define:
var flag = false;
Your success function should be:
success: function (data) {
if (data != '') {
var response = $(data).find("#gmp_stuff").html();
employee_email = $(data).find(".EMP_EMAIL>span").html();
//alert(employee_email);
$("#user_responses").html(response);
//$(function () {
$("#user_responses").dialog({
dialogClass: 'transparent',
resizable: false,
draggable: false,
modal: true,
width: 1000,
autoOpen: false,
overlay: { opacity: 0 }
});
$('#user_responses').dialog('open');
$('#user_responses').css('display', '');
//});
flag = true;
}
}
And sendEmail() can be:
function sendEmail(){
if(flag)
{
request = $.ajax({
url: "send_email.php?"+employee_email ,
type: "post",
success: function(data){
$("#email_responses").html();
},
error:function(){
alert("failure");
$("#email_responses").html('error occured');
}
});
}
else
alert('Sending email is unavailable currently. PLease try after some time.');
}
Even though this have been answered hundreds of times on SO, I can give you a short explanation.
Since you're dealing with 2 asynchronous calls, you can never access data from the first call in a normal syncronous flow.
Make your first function return your $.ajax
function showCustomer(){
return $.ajax({ /* ... */ });
And access the data returned in a callback:
showCustomer().done(function(data){
console.log($(data).find(".EMP_EMAIL>span").html());
});
This assumes that you're using jQuery 1.5 or above, where the ajax calls exposes a promise.
An other alternative would be to nest the ajax calls (call the second one in the first ones success handler).
You're updating the value employee_email through AJAX call. As soon as first function is called, it makes AJAX call and moves to second function. The second function won't see the value change yet and employee_email doesn't change at all.
You've 2 options -
Use second function in done of first function.
Use Deferred object in first call and on done of it call the second function.
Related
I am trying to get the response time of an ajax request and use it in a setTimeout() function, this function displays a loader that is suppose to keep loading until we get the response.
Here's my function :
$("#recalculer").click(function(){
ajax_call();
setTimeout(function()
{
$("#divgris").fadeTo(0,1);
$("#loadingdiv2").hide();
}, 5000);
});
And here's my ajax request :
function ajax_call()
{
var resultat;
var duree_souhaitee= $("#duree").val();
var apport_personnel= $("#apport").val().replace(/\s+/g, '');
var prix_achat_bien=$("#prix").val().replace(/\s+/g, '');
$.ajax({
type: "POST",
url: "/iframe/rest-assurance",
data : {
"duree_souhaitee" : duree_souhaitee,
"apport_personnel" : apport_personnel,
"prix_achat_bien" : prix_achat_bien
},
dataType: 'json',
xhrFields: {
withCredentials: true
},
async: true,
beforeSend: function(){
$("#actualiserAssurance").hide();
},
success: callback_assurance
});
}
For now i set a time of 5000 but i need to replace it with the ajax response time, how can I achieve that ?
I use always:
$("#loadingdiv2").show();
$.ajax(
...
).always(function(){ $("#loadingdiv2").hide(); });
If you want to separate it from the Ajax call I would use a custom event.
$("#recalculer").click(function(){
ajax_call();
});
$("body").bind('custom.ajaxStart', function(){ $("#loadingdiv2").show(); });
$("body").bind('custom.ajaxStop', function(){ $("#loadingdiv2").hide(); });
function ajax_call(){
$('body').trigger('custom.ajaxStart');
$.ajax(..).always(function(){ $('body').trigger('custom.ajaxStop'); });
}
The always callback is triggered even on a 404, relying on timing never works well for me.
Using an event gives you the flexibility of calling the loading deal, from anywhere.
Meaby the you can use:
console.time(label);
and
console.timeEnd(label);
more info can be found here.
Goodluck!
use
var afterfnc = ()=>{
$("#divgris").fadeTo(0,1);
$("#loadingdiv2").hide();
}
and then set
callback_assurance = afterfnc
in ajax call
I am trying to communicate with a server using JSONP call back.
Here is my code
$('.icwsDownloadRecording').click(function(){
var id = $(this).attr('data-recordingid');
$.ajax({
type: 'GET',
url: 'http://example.com/Default2.aspx',
data: {'ID': id},
dataType: 'jsonp',
cache: false,
timeout: 40000,
crossDomain:true,
jsonp: "MyCallbackFunction",
});
});
function MyCallbackFunction(data)
{
//process data further
console.log(data);
if(!data || data.url.length < 5){
return;
}
var $preparingFileModal = $("#preparing-file-modal");
$preparingFileModal.dialog({ modal: true });
$.fileDownload( data.url, {
successCallback: function (url) {
$preparingFileModal.dialog('close');
},
failCallback: function (responseHtml, url) {
$preparingFileModal.dialog('close');
$("#error-modal").dialog({ modal: true });
}
});
return false; //this is critical to stop the click event which will trigger a normal file download!
}
The issue here is that I keep getting this message in the console
ReferenceError: MyCallbackFunction is not defined
I do have this defined as you can see in my code above
The server respond looks like this
MyCallbackFunction("{'URL': 'http:\/\/example.com:8106\/ghjgj3835396265336634646562363030303122226D616C686179656B22535353557DBE0C305645E2DE110AA1D7F8792E96A3'}");
how can I correct this issue?
EDITED
This is my code after Quentin Answer , this is my new code
$(function(){
$('.icwsDownloadRecording').click(function(){
var id = $(this).attr('data-recordingid');
$.ajax({
type: 'GET',
url: 'http://example.com/Default2.aspx',
data: {'ID': id},
dataType: 'jsonp',
timeout: 40000,
success: function(data){
//process data further
console.log(data);
if(!data || data.url.length < 5){
return;
}
var $preparingFileModal = $("#preparing-file-modal");
$preparingFileModal.dialog({ modal: true });
$.fileDownload( data.url, {
successCallback: function (url) {
$preparingFileModal.dialog('close');
},
failCallback: function (responseHtml, url) {
$preparingFileModal.dialog('close');
$("#error-modal").dialog({ modal: true });
}
});
return false; //this is critical to stop the click event which will trigger a normal file download!
}
});
});
});
Unless you have all of that code wrapped in another function, that should work.
Using a hardcoded function name is bad practise though.
Update:
$(function(){
You do have all that code wrapped in another function.
Remove this:
jsonp: "MyCallbackFunction",
Replace it with:
success: MyCallbackFunction
Or you could put an anonymous function expression there instead (as you have done in your edit)
Let jQuery generate a unique function name (which protects you from race conditions) and allow the server to use the callback query string argument to determine what function name to use.
MyCallbackFunction is in the same scope as the ajax call, so it will be available to the function (which can copy it to a suitably named global).
After you fix that, you have an additional problem:
MyCallbackFunction("{'URL':
Your response is JSON encoded in a JavaScript string, but you are trying to treat it as a JavaScript object.
Either:
Fix the server so it doesn't stringify the JSON or
Run the first argument through JSON.parse
crossDomain:true,
Remove that. It doesn't do anything here. (All it does is, when using XHR (which you aren't using) to the same origin (which you aren't targeting), suppress the custom headers that aren't typically allowed on a cross-origin request so that you can perform an HTTP redirect to a different origin).
cache: false,
That's the default for JSONP requests. Including it is pointless.
return false; //this is critical to stop the click event which will trigger a normal file download!
If you want to stop the click event, then you need to return false from the click event handler function (not the Ajax success handler).
You can't wait until the Ajax function has run and got a response before doing that. Ajax is asynchronous.
I'm writing a javascript function that should change the view of a postcard depending on which case is selected.
My problem is that the old values of the object "m_case" is getting used. If I press the button with class "case-btn" twice I get the right case selected in my postcard view. But I want it to be triggered when I press the button once.
I guess I have to do something like a callback function in the m_case.setCase() function call, but I can't get it working,
$('.case-btn').on('click', function() {
remove_active_state_from_cases();
m_case.setCase($(this).data('case'));
// Changes the view of the postcard
m_postcard.changeBackground(m_case.getPhoto());
m_postcard.changeMessage(m_case.getMessageText());
m_postcard.changeFullName(m_case.getFullName());
m_postcard.changeCountry(m_case.getCountry());
$(this).toggleClass('active');
});
The setCase() function
this.setCase = function(id) {
// Set ID
this.setID(id);
var that = this;
$.ajax({
url: 'get_case_by_id.php',
type: 'get',
dataType: 'json',
data: {id: that.getID() },
success: function(data) {
if(data.success) {
that.setFirstName(data.first_name);
that.setFullName(data.full_name);
that.setAdress(data.adress);
that.setCountry(data.country);
that.setStamp(data.stamp);
that.setPhoto(data.photo);
that.setSummary(data.summary);
that.setStory(data.story);
that.setMessageText(data.message_text);
that.setDefaultMessageText(data.default_message_text);
that.setMessageImg(data.message_img);
} else {
console.log('failure');
}
}
EDIT The problem might be in my AJAX call, I have to wait till the ajax have been called. but how do I continue the first flow when my Ajax is done and not before?
SOLUTION
I made it working by adding a callback parameter and calling that function in the ajaxs complete function.
$('.case-btn').on('click', function() {
remove_active_state_from_cases();
var that = this;
m_case.setCase($(this).data('case'), function() {
m_postcard.changeBackground(m_case.getPhoto());
m_postcard.changeMessage(m_case.getMessageText());
m_postcard.changeFullName(m_case.getFullName());
m_postcard.changeCountry(m_case.getCountry());
$(that).toggleClass('active');
});
});
// Sets the whole case from an id.
this.setCase = function(id, callback) {
// Set ID
this.setID(id);
var that = this;
$.ajax({
url: 'get_case_by_id.php',
type: 'get',
dataType: 'json',
data: {id: that.getID() },
success: function(data) {
if(data.success) {
that.setFirstName(data.first_name);
that.setFullName(data.full_name);
that.setAdress(data.adress);
that.setCountry(data.country);
that.setStamp(data.stamp);
that.setPhoto(data.photo);
that.setSummary(data.summary);
that.setStory(data.story);
that.setMessageText(data.message_text);
that.setDefaultMessageText(data.default_message_text);
that.setMessageImg(data.message_img);
} else {
console.log('fail big time');
}
},
complete: function() {
callback();
}
});
}
Your m_postcard.changeBackground and other calls should be in the success callback, or in another function that is called from the success callback, as those values aren't set till the async ajax call is done.
With the way your code is now the m_postcard.changeBackground and other calls are called immediately after your setCase function is done executing. This means your methods are executed before the data has arrived from the server
While the ajax is processing you probably should show a loading message on the screen to let the user know they have to wait till the processing is done. Show the message before calling the .ajax call and hide it in the success/error callbacks.
Any changes to the site content should be done from the success callback, ie changing active states, changing content, etc.
I am using jQuery getJSON() function. This function getting data with no problem. But sometimes waiting, waiting waiting... And my loading bar showing loading loading loadin at center of page.
So jQuery ajax() function have an timeout variable. But i want to use getJSON function. And i think that i can use ajaxStart() and ajaxStop() functions. But how?
$('.loadingDiv')
.hide()
.ajaxStart(function() {
$(this).fadeIn();
setTimeout("throw '';",15000) //i used this but didn't work
setTimeout("return;",15000) //i used this but didn't work
setTimeout("abort();",15000) //i used this but didn't work.(Abort all ajax events)
})
.ajaxStop(function() {
$(this).fadeOut();
});
getJSON() returns a promise on which you can call the abort function :
var p = $.getJSON(..., function(){ alert('success');});
setTimeout(function(){ p.abort(); }, 2000);
EDIT : but if your goal is just to abort if it takes too much time, then lethal-guitar's answer is better.
getJSON() is just a shorthand for the following:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
So you could use $.ajax() and specify the timeout option as desired. See also: http://api.jquery.com/jQuery.getJSON/
As lethal-guitar mentioned getJSON() function is just an shorthand for $.ajax(). If you want to detect if a timeout has occurred rather than an actual error use the code below.
var request = $.ajax({
dataType: "json",
url: url,
data: data,
success: function( ) { },
timeout: 2000
}).fail( function( xhr, status ) {
if( status == "timeout" ) {
// do stuff in case of timeout
}
});
There's always the nuclear route as well:
//Set AJAX timeout to 10 seconds
$.ajaxSetup({
timeout: 10*1000
});
This will set all the AJAX requests your program makes (even via $.getJSON) to have a time out of 10 seconds (or what have you).
the setTimeout function executes a set of code after a specified number of milisecons in the global scope.
The getJSON function (per the jQuery documentation here http://api.jquery.com/jQuery.getJSON/) is shorthand for:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success
});
so you would want to make your call like so:
$.ajax({
dataType: "json",
url: url,
data: data,
success: success,
timeout: 15000
});
$('.loadingDiv')
.hide()
.ajaxStart(function() {
$(this).fadeIn();
})
.ajaxStop(function() {
$(this).fadeOut();
});
I don't think any of these answers are ideal. I know this is years late, but what you want to do is use the success/error callback options of the .ajax(); method when receiving a JSONP response.
Example of how I would structure this:
// Call
$.ajax({
// URL you want to get
url: 'http://example.com/json?callback=?',
// Set a realistic time in milliseconds
timeout: 3000,
// Put in success callback function here, this example
// shows you the data you got back from the call
success: function(data) {
console.log(data);
},
// Put in an error handling function, just an alert in this case
error: function(badData) {
alert('The call was unsuccessful');
},
type: 'POST'
});
My scripts are working perfectly fine. However, the content does not refresh itself to get new data. Why is it so?
function updateMsg() {
$.ajax({
url: "/recent/notifications/",
cache: false,
success: function(html){
$("#profile_notifarea_msgbox").html(html);
}
});
setTimeout('updateMsg()', 4000);
}
updateMsg();
Your setTimeout can reference updateMsg directly instead of using a string:
var timeout;
function updateMsg() {
$.ajax({
url: "/recent/notifications/",
cache: false,
success: function(html){
$("#profile_notifarea_msgbox").html(html);
timeout = setTimeout(updateMsg, 4000);
}
});
}
updateMsg();
function stopUpdate() {
clearTimeout(timeout);
}
To stop the continuous update you save a reference to the setTimeout in a variable and then call clearTimeout and pass in that variable. In this example, you would just call the function stopUpdate() to cancel the updates.
when you use ajax with jQuery try to always put an error function, in this way you can identify if something is wrong with the request