Im trying to sort this around, im making an ajax requests of get type, and the page will be returning many responses, OK is one of those, is the page returns OK then I need to proceed for form submitting, else I need to halt the form submission, but Im unable to access the data out side of the function, it is available inside the fall back function alone, is it due to asynchronous mannerism?, can some one assist me to get out of this?
$.get('ajax.html',function(data){
//some code here
});
if(data == 'ok'){return true; } else {return false;}
$.get fires an asynchronous request, and the execution of you program continues. So in your case data is available only after the ajax call finishes and only inside your callback function. You need to do whatever you want to do with data inside your callback function.
You need to re-arrange you code to do something like:
$.get('ajax.html', function (data) {
if(data === 'OK') {
// do what you need to do in this case
}
});
// at this point there's no data
No, you are accessing data which is not a variable available.
How about assigning it to another variable?
var resp = "";
get('ajax.html', function (data) {
resp = data;
});
if(resp == "OK") {alert(1);}
alternatively you can go use asyn false
$.ajax({
url: url,
type: "GET",
async: false,
data: data,
success: function(ret) {
//alert(ret);
resp = data;
}
});
alert(resp);
Cheers!
Related
I have what might be a tricky question.
I am working on a form where it verifies a couple things on submit, using event.preventDefault(); to prevent the form from submitting if something went wrong. The issue here is that it sends multiple ajax requests at the same time, which seems to stop the php (which is processing the AJAX call) from modifying the $_SESSION variable.
I have determined this by changing the jquery ajax calls to process synchronously, allowing the $_SESSION variable to be changed.
My question is this: is there a way to allow the ajax calls to happen synchronously while allowing the $_SESSION variable to be modified during the process of those calls? I realize that the async:false for an AJAX call is deprecated, and obviously not the best solution.
Due to what each call does, it is not possible to combine the functionality of these two calls, although each call does not take long at all to process.
Example jquery code to explain how I am making these AJAX calls (some redaction and simplification, obviously):
$("#form-id").on('submit', function(event) {
$.ajax({
type: 'POST',
url: '/url/to/processing.php',
async:false, //fails without setting to false
...
});
});
...
$("#form-id").on('submit', function(event) {
$.ajax({
type: 'POST',
url: '/url/to/processing2ThatSetsSession.php',
async:false, //fails without setting to false
...
});
});
You have to concat the calls, to run one call after the other has ended.
I'll do it this way:
function ajaxPost(url, callback) {
$.ajax({
type: 'POST',
url: url
...
}).done(callback);
}
$("#form-id").on('submit', function(event) {
event.preventDefault(); // Always stop the event
// Do one ajax call and wait for the data
ajaxPost('/url/to/processing.php', function(data) {
// Do things with returned data and call the next ajax
ajaxPost('/url/to/processing.php', function(moredata) {
// Do something with moredata
// If everything is fine, re-post it but this time do not catch the event
$("#form-id").off("submit").submit();
});
});
});
You can add your own logic to show your error message in any callback and not continue with the next one.
With this I'll do an special method for multiple ajax form validation:
// This function will get an array of objects and
// do an ajax call and process the data, one after another
function multiAjax(calls, callback) {
var call = calls.shift();
if (call) {
var url = call.url;
post(url, function(data) {
var error = call.process(data);
if (error) {
callback(error);
} else {
multiAjax(calls, callback);
}
});
} else {
callback();
}
}
// This is the array of objects that multiAjax will process.
// You can add or remove elements to your likings, without modifying
// the submit event callback
var ajaxArray = [{
url: '/url/to/processing.php',
process: function(data) {
if (data.isWrong()) {
return "The data is wrong";
}
}
}, {
url: '/url/to/processing.php',
process: function(data) {
if (data != "OK") {
return "The data is not OK";
}
}
}];
// Now listen for the submit event
$("#form-id").on('submit', function(event) {
// Always stop the event
event.preventDefault();
// Do multiple ajax calls in one function call.
// Because the array is mutated inside multiAjax() (yeah, bad design but I've
// done this fast as an example), we slice() the array to get a new one
multiAjax(ajaxArray.slice(), function(error) {
if (error) {
// Show the error received
} else {
// submit the form the same way above
$("#form-id").off("submit").submit();
}
});
});
This is all untested code, but you get the point.
If one form submission is making two posts to the same PHP server, you should rethink the architecture instead of building complicated workarounds.
I would POST to a single PHP script that will do everything you need in the backend.
$.ajax({
type: 'POST',
url: '/url/to/all-processing.php',
... // send all the data needed by all processes
});
On the PHP side: all-processing.php
session_start();
require_once './process1.php';
require_once './process2.php';
Sorry folk, I know that my question asked many guys in different form, but I'm disappointed to find a decision my problem.
function testAjax(){
var result = "";
$.ajax({
type: "POST",
dataType: 'jsonp',
url: "https://api.novaposhta.ua/v2.0/json/",
data: {
"modelName": "Address",
"calledMethod": "getCities",
"methodProperties": {},
"apiKey": "6f94a6391cb5134ee68ddb7924de2a3d"
},
success: function(msg) { result = msg }});
return result;
}
var kor = testAjax();
console.log(kor);
I need to take out data from the ajax request and assign this data to a global variable. But function testAjax returns nothing. I think testAjax returns nothing because it's an async request to server and completes later than return result.
My question - how do I take out a value from $.ajax() and assign this value to a global variable? I tried googling and try decide this problem, but ...
Yes, your hunch is correct - the function is returning result as an empty string because the success handler is called later when the server response is returned. If you wish to do something specific when the response comes in, do so in the success response handler like so:
...
success: function(msg) {
// now you have the response so do something with it
console.log(msg);
}
...
most of the time the logic go inside the success function, whatever you will do with the response do it inside the success function.I think you may bay more time for the code structure and the flow of data inside your app.
good luck
I have to make an ajax call and decide based on the response whether to navigate away from a page or not. Here is what I've tried so far.
window.onbeforeunload = function(e) {
$.when($.ajax({
url: checkUrl,
async: false,
type: 'GET',
})).then(function(data, textStatus, jqXHR){
if(data===false)
return "Appointment not created yet. Do you wish to leave?";
else
return false;
});}
When I use the debugger to check the flow of control it seems to wait till the data is returned but it would not display the alert box.
I am not sure what I am doing wrong. I know there have been similar questions but could not find a solution. Help me find a way to make it work
You're not returning the string from your onbeforeunload function. You're returning it from the then callback.
You need to set a variable that you use to return from the main function instead:
window.onbeforeunload = function(e) {
var result = undefined;
$.when($.ajax({
url: checkUrl,
async: false,
type: 'GET',
})).then(function(data, textStatus, jqXHR){
if(data===false) {
result = "Appointment not created yet. Do you wish to leave?";
}
});
return result;
};
Side note: There's no need for the $.when in that, you can use the "promise" returned by $.ajax directly:
window.onbeforeunload = function(e) {
var result = undefined;
$.ajax({
url: checkUrl,
async: false,
type: 'GET',
}).then(function(data, textStatus, jqXHR){
if(data===false) {
result = "Appointment not created yet. Do you wish to leave?";
}
});
return result;
};
Side note 2: Insert usual note here about how synchronous ajax blocks the UI of the browser. If you're doing an appointment creation, surely you can set a client-side variable when you start creating it, then clear it when you're done, and use that to know whether to show a message?
Side note 3: Modern browsers ignore the message you return and just show something generic. I'm not saying you should change anything (because there are still some that show it, for now), just mentioning it so you don't go nuts trying to figure out why you're getting a message, but not your message.
Side note 4: Your then callback will only receive a single argument. The three arguments you've listed are the ones passed to the success callback, not the then callback.
I am wondering is these is any way to access the results of a jquery ajax call in the form a traditional var set to function fashion. For example consider:
function getPoints(){
//An array of JSON objects
var Points;
$.ajax({
url: "js/retrievePointsDataJson.php",
dataType:'json',
type: 'POST',
}).done(function(data){
//console.log(data);
Points.append(data);
});
console.log(Points);
return Points;
}
The commented out console.log show the array of json objects whereas the outer one does not. Now, i have tries this:
var Points = $.ajax({ ...});
And i see the response text within a larger object, but am unsure how to access the responseText. console.log(Points.responseText) yields an undefined variable.
Is this possible with this approach? Here is another question that received a check mark with a similar issue.
I have another solutions, which is the encapsulate my code within the done() function and i will have access to all my data. I was just curious if what i am attempting to do is even doable.
Thank you.
yes it is possible, however, you must wait for the request to be complete before doing so. However, since you can't effectively force the return to wait until the data exists, you're only options are to return a deferred object instead, or re-write the function in such a way that allows it to accept a callback.
function getPoints(){
return $.ajax({
url: "js/retrievePointsDataJson.php",
dataType:'json',
type: 'POST'
});
}
getPoints().done(function(data){
console.log(data);
});
or
function getPoints(callback){
return $.ajax({
url: "js/retrievePointsDataJson.php",
dataType:'json',
type: 'POST',
success: callback
});
}
getPoints(function(data){
console.log(data);
});
Because the Ajax call is done asynchronously you shouldn't return it from the outside function. This would require that you somehow block until the asynchronous call completes. Instead you could pass in a callback function to the getPoints function that will handle the logic of using the points.
function getPoints(callback){
$.ajax({
url: "js/retrievePointsDataJson.php",
dataType:'json',
type: 'POST',
}).done(function(data){
callback(data);
});
}
The asynchronous nature of ajax can make things harder if your used to imperative programming, but it will make your user interface much more responsive.
The log you're calling in the outer function is working with an undefined variable because the function is asynchronous. You can't return it from getPoints because it won't have finished. Any work with the Points variable needs to happen inside the callback (the function passed to done).
I have the following code which is included in a keypress function:
$.getJSON('dimensions.json', function(data) {
$.each(data, function(index) {
$('#div1').append(index);
});
});
I'm trying to first get the JSON string, save it in a variable and then run the each(). I want to basically separate the each() to be unlinked to the getJSON() function because I don't want it to fetch the json file for every keypress.
I've tried this, but it didn't work:
var JSONstr = $.getJSON('dimensions.json');
$.each(JSONstr, function(index) {
$('#div1').append(index);
});
In your first example, you do $.each in the callback. The callback is executed by some other callback after there result is received, while $.getJSON returns immediately without waiting for the result (since there is no blocking in JavaScript by design).
Therefore the code in your second example can never work: the $.each begins before any result is received from the web server, probably even before the request is sent. Whatever the return value of $.getJSON is, it can't, by the design of JavaScript, be the result of AJAX request.
UPD: Saw your comment, now I understand what you wanted to do. Here's a simple example of how to do this:
function ActualHandler(data) {
$.each(data, function(index) {
$('#div1').append(index);
});
}
function KeypressHandler() {
if (window.my_data) { // If we have the data saved, work with it
ActualHandler(window.my_data);
}
else { // Otherwise, send the request, wait for the answer, then do something
$.getJSON('dimensions.json', function(data) {
window.my_data = data; // Save the data
ActualHandler(data); // And *then* work on it
});
}
}
Here, the ActualHandler is not launched before the data is received, and once that happens, all subsequent clicks will be handled immediately.
The downside in this particular case is that if user clicks again while the first request is running, one more will be sent. But to fix that you would need to maintain some queue, which is kind of out of scope here.
You fell into the asynchronous trap. Your $.each() function doesn't wait for your $.getJSON() call to get the data. You can get around this by using the good 'ol $.ajax() function. Like this:
function processJSON(data) {
$.each(data, function(index) {
$('#div1').append(index);
});
}
$.ajax({
url: 'dimensions.json',
dataType: 'json',
async: false,
success: processJSON(data)
});