Retrieve array data from JQuery Ajax function into javascript - javascript

I'm trying to store data that I am retrieving from my JSON Ajax function. When I console output the data from inside the ajax function it works fine but when I try to do the same with the data variable it is failing.
Am I not storing the resulting data correctly?
function f_find() {
// create my data object from the results
var result = $.ajax({
url : '../scripts/php/users/f_users.php',
type : 'GET',
dataType : "json",
data : {'action':'find'},
success : function(data) {
// this bit works
console.log(data[0]["field01"]);
console.log(data[1]["field01"]);
},
error : function(log) {
console.log(log.message);
}
});
// this shows me that my result is an object
console.log(result);
// this bit fails
console.log(result[0]["field01"]);
console.log(result[1]["field01"]);
}
The php is as follows
<?php
if(isset($_GET['action'])) {
switch($_GET['action']) {
case 'find':
f_find();
break;
default:
echo json_encode();
return;
break;
}
}
function f_find() {
$la_info = array();
$la_info[0]["field01"] = "index 0 field 1";
$la_info[0]["field02"] = "index 0 field 2";
$la_info[1]["field01"] = "index 1 field 1";
$la_info[1]["field02"] = "index 1 field 1";
echo json_encode($la_info);
}
?>

The ajax call happens asynchronously. The "failing" is actually just running before the ajax responds. Look in your console and notice that your two failing console.logs write to to the console BEFORE the two "working" console.log statements.
Also... the "data" variable will only be accessible within the scope of that "success" callback unless you store its value in the global scope. window.data = data;

You have trouble with your scope.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
Try this :
function f_find() {
var ajaxResult = null;
// create my data object from the results
$.ajax({
url : '../scripts/php/users/f_users.php',
type : 'GET',
async: false,
dataType : "json",
data : {'action':'find'},
success : function(data) {
// this bit works
ajaxResult = data;
console.log(data[0]["field01"]);
console.log(data[1]["field01"]);
},
error : function(log) {
console.log(log.message);
}
});
console.log(ajaxResult[0]["field01"]);
console.log(ajaxResult[1]["field01"]);
}
When you receive data form ajax success they are now available in the ajaxResult var. In this example i said to ajax to be synchronous to prevent console.log call before you receive your ajax callback.
You can also do this with this notation :
function f_find() {
// create my data object from the results
$.ajax({
url : '../scripts/php/users/f_users.php',
type : 'GET',
dataType : "json",
data : {'action':'find'},
error : function(log) {
console.log(log.message);
}
}).done(function(data){
console.log(data[0]["field01"]);
console.log(data[1]["field01"]);
});
}
But you still can't access data outside of the done scope.

As #Dekel says, this is a timing issue (apart from the weirdness over the two data variables). Kevin Grosgojat's answer will still have the timing issue.
The $.ajax function is asynchronous. What that means is that the ajax function fires off the data request to the server and while that is being processed at the server, processing proceeds on to hit your two external console outputs however at this point in time the server has not responded and so there is no data to display. Some time later the server responds to the ajax call and your internal console logs spit out the answer that you anticipated.
'IF' your original code were to work for you now it would be because you have a very fast server or very small server process to get the data, but it would surely suffer and be an intermittent bug in production.
You 'could' add the parameter to the ajax function to make it run synchronously (meaning wait for server response) but that is rarely what you would truly want as the final solution.

Related

Display Flask JSON datas with Jquery

I'm trying to display json data coming from my flask function.
I can use getJson method to get those datas but getJSon work with action like click or change.
getJSon return data but i can't use use them out of the function.
For example
$.getJSON('../admin/graphe_1', {
}, function(data) {
chart.data = data
console.log(data)
});
console.log(chart.data)
The first console log display data but the second one display nothing.
How can I do to get this data out of the function ?
Reason is getJSON function is asynchronous. So your second console.log prints the data before actually loaded into your app. So it prints null probably. The first console.log is in the function which executed right after completing loading data successfully. So it should print correct data. If you want to do stuff after loading data successfully do it in the done function which contains your first console.log. if you want synchronous execution use,
$.ajax({
dataType: "json",
url: url,
async: false,
data: data,
success: function (data){
chart.data=data;
}
});
console.log(chart.data); // data should be loaded
This is not recommend since it blocks UI thread.

Getting null in return when executing Ajax request

Ajax request is executing, but it returns not curent_day variable but null.
Js:
$.ajax({
url: 'planing/next-day',
data: {new_curent_day: $('.owl-item.center .slide_day').text()},
dataType: 'json',
type: 'POST',
success: function(curent_day) {
alert(curent_day);
},
error: function(xhr, status, error) {
alert(xhr.responseText + '|\n' + status + '|\n' +error);
}
});
Controller:
public function actionNextDay() {
if (Yii::$app->request->isAjax){
$this->planing_model->curent_day = Yii::$app->request->post('new_curent_day');
return Json::encode($this->planing_model->curent_day);
}
}
May be the problem is your are sending the POST data as JSON so your not able get it through
Yii::$app->request->post('new_curent_day');
Try this they have updated JSON parser set and to get the JSON value through yii.
Error in accessing post json data in yii2
Use the Javascript console and debugger in your browser to see what $('.owl-item.center .slide_day') contains. Make your API endpoint log what it gets in the post variables.
The typos in variable names make me worry that you might refer to the wrong thing. planing has two n's, curent has two r's. This code looks consistent at least but if I came across this code I would suspect current and curent got mixed up.

javascript - variable scope

This is a silly question, but I'm trying to use the contents from var form_data outside the ajax scope. How would I go about doing this? form_data only seems to exist inside the ajax function rather than outside even after declaring the variable outside of the ajax scope. I thought variables bubbled up until it finds where it was declared when var isn't defined.
To clarify my question, how do I use the results from the server outside the success function? I don't want to limit myself to doing everything inside the ajax success callback.
$(function () {
var form_data;
$.ajax({
type: 'GET',
url: 'print_form.php',
data: {
//data sent to server
},
success: function (response) {
form_data = JSON.parse(response);
console.log(form_data); //object is printed out as expected
},
error: function () {
alert('AJAX failed for print_form');
}
});
console.log(form_data); //undefined
});
As AJAX stands for Asynchronous Javascript and Xml, so your code doesn't get blocked for an ajax operation being executed as it's asynchronous. In your case what happen is that when you are getting data through ajax your javascript doesn't stop continuing of execution and wait for the request to get success. Rather then that, while you are getting the data the rest of the code still gets executed. And that's why before you get the from the server through ajax request the form_data already gets printed outside of the ajax request scope.
Let's test it :
Try initializing form_data with any value. You'll find that now you won't get undefined outside the ajax where you printed the value. Rather you'll get the value you initialized the variable with.
An alternative construct to the success callback option, the .done()
method replaces the deprecated jqXHR.success() method. Refer to
deferred.done() for implementation details.
source: http://api.jquery.com/jquery.ajax/
Build your code as given in the docs:
I am having success with this setup that isolates the Ajax call.
function sendAjax(xhrdata) {
return $.ajax({
type: 'GET',
url: 'print_form.php',
data: xhrdata
}).promise();
}
sendAjax(data).done(function(response) {
form_data = JSON.parse(response);
console.log(form_data);
}

how to access input data submitted to ajax request (NOT return data) via jQuery

I'm trying to retrieve the data I submitted to an asynchronous ajax request should the back-end fail in some way. The data in 'myJSONData' is actually pulled off a queue (array) in memory and I need to put it back into the queue if any kind of error occurs.
e.g.
var myJSONData = {"parm1":"value1","parm2":"value"};
$.ajax({
type: "POST",
url: "/postData.ajax",
dataType: "json",
data: myJSONData,
success: function(jsonReply) {
// I need to refer to the posted data here (i.e. myJSONData)
},
error: function(xhr,ajaxOptions,thrownError) {
// I need to refer to the posted data here (i.e. myJSONData)
}
});
My code fires off a number of calls at various times, the trouble is that if I refer to myJSONData within the success or error blocks it contains the most recent value of that variable in memory, and not what was in the variable at the time of the ajax call.
Is there some other way to access the data associated with the particular instance of ajax call - something like $.ajax.data ?
You should be able to access it in your success and error functions :
success: function(jsonReply) {
var p1 = myJSONData.param1;
}

Iterate on array, calling $.ajax for each element. Return array with all ajax results

I've just started working with JavaScript for non-trivial things, so this is probably straightforward...
What I'm trying to accomplish: iterate on an array of product references, fetch the JSON for each reference, and return an array of all the product information (with a hash-like structure indexed by reference).
What I've tried:
function fetchProductData(references){
var product_data = new Object();
references.forEach(function(ref){
$.ajax({
url: "http://localhost:3000/products/find.js?reference=" + ref,
dataType: "jsonp",
type: "GET",
processData: false,
contentType: "application/json",
success: function(data) {
product_data[ref] = data;
}
});
});
alert('before return: ' + product_data);
return product_data;
};
$(document).ready(function(){
var products = fetchProductData(references);
alert('products : ' + products);
});
Here's what I don't understand: the first time I call alert to display the array contents, the array is empty. However, on the second call, the array is populated with the data I want.
In other words, the "products :" alert displays the data I want in the code above. But if I comment the "before return: " alert, it no longer does. Why is this?
So my question is: how can I have jQuery make several $.ajax call to fetch product information, collect that information in an array, and return that array so I can use it elsewhere in my code?
Also, why is the data in the variable magically accessible after it is referenced in an alert?
The "A" in "AJAX" stands for "asynchronous" :). Your program doesn't wait for the call to complete before going on to the next iteration, meaning you'll probably not get all of your data. Also the alert has the same problem. Operation to concat 'before return:' to the string add just enough time to get some data in the variable. On a faster machine you might find you never get data.
I think you really need to rethink your approach. It's not a good idea to have multiple AJAX requests in a loop. It will greatly increase latency of the page. Pass all your parameters once using JSON, then have your server side script loop through that and return a single response in JSON.
function fetchProductData(references){
// make sure your "references" is a JSON object
$.getJSON('http://server/side/url', {'json':references}, function(product_data) {
// do something with product_data (alert them, put them in an array, etc)
});
}
function fetchProductData(references, cb){
var length = 0;
var product_data = new Object();
references.forEach(function(ref){
length++;
$.ajax({
url: "http://localhost:3000/products/find.js?reference=" + ref,
dataType: "jsonp",
type: "GET",
processData: false,
contentType: "application/json",
success: function(data) {
product_data[ref] = data;
if (++count === length) {
cb(product_data);
}
}
});
});
};
$(document).ready(function(){
var products = fetchProductData(references, function(products) {
alert('products : ' + products);
});
});
Use a callback on your asynchronous operation.
The reason it appears to work with the alert call is because alerting a message gives ajax enough time to populate your array. The return statement is only triggered after you click OK on the alert box giving your code a window of 250ms to populate the array with data.
You are executing you ajax query in async mode. And you want a sync result. Try to add:
async: false
Hope this helps.
your $.ajax call is asynchronous, so what is happening is that the first time you make the call, your javascript makes the call, moves on to the next line (alert) and then loops. You're data hasn't returned at that point yet. What you can do to remedy this is to set the async: false option in your $.ajax call.
This is an asynchronous operation. The only sure way to know when the data is ready is in the callback function: success: function () {...}, which gets called when the data has finally returned. Put your alert in there.

Categories