Is there any way I can obtain the data from a JSON file and save them into a multidimensional array in JavaScript.
The JSON file is a .php file with header set to JSON.
I've tried so far:
var questionJSONS="";
$(document).ready(function(){
var questionJ="";
$.getJSON("http://localhost:8080/audioMillionaire/test2.php",function(result){
$.each(result, function(i, item){
questionJ+= "['"+result[i].qid+"','"+result[i].description+"','"+result[i].a+"']";
});
setArray(questionJ);
});
});
And many other things, but none of them seem to work.
I think this is what you meant:
$(document).ready(function() {
var questions = [];
$.getJSON("http://localhost:8080/audioMillionaire/test2.php", function(result) {
$.each(result, function(i, item) {
questions.push([result[i].qid, result[i].description, result[i].a]);
});
});
});
If not, please comment.
Edit: BenM was faster
Edit:
This works as well, but I cannot use the array outside of $.getJSON
This is because you are probably using code like this:
...
questions.push([result[i].qid, result[i].description, result[i].a]);
});
});
console.log(questions);
Because javascript is an asynchronous language the console log call happens before the pushes after the json was requested. You can read more about it here.
$(document).ready(function() {
console.log("set test to old");
var test = "old";
setTimeout(function() {
console.log("set test to new");
test = "new";
console.log("inside timeout: " + test);
}, 3000); // runs in 3 seconds
console.log("outside timeout: " + test);
});
This code should provide a good example. The function setTimeout just waits 3 seconds and runs the function (much like the json request).
Knowing this you should find a solution on your own (like calling a passed function after the array has been pushed). If not comment.
Edit: changed link to other, better page.
In your example, questionJ is being treated as a string, and without seeing your setArray() function, it's difficult to say for sure what's wrong (I don't know if you're parsing the string inside this function, for example).
However, assuming that you wish for questionJ to be an array of arrays, the following should work:
questionJSONS = [ ];
$.getJSON('http://localhost:8080/audioMillionaire/test2.php', function(result){
$.each(result, function() {
questionJSONS.push( [ this.qid, this.description, this.a ] );
});
});
Notice that inside the $.each function, you can reference this, which refers to the currently iterated item. Using this method (with push() and the array data structure) directly, the datatype is also preserved from the JSON.
Also, since you're not directly interacting with the DOM inside of the snippet, there's no requirement to wrap it inside the DOMReady handler.
Related
I'm trying to read data from a json file into JavaScript so it can be used by other functions that are called when a user interacts with the page. I've tried, using jQuery and JS:
var products = null;
$.getJSON("products.json", function(data) {
products = data;
console.log(data);
});
console.log(products);
Which produces, as expected:
null
Array [ {…}, {…} ]
I understand this is because of the asynchronous nature of the jQuery code execution. I've read into it a bit, but I'm just struggling to wrap my head around how to re-structure my code (coming from pretty much exclusively Python).
This is how I'm seeing it:
var products = null;
$.getJSON("products.json", function(data) {
products = data;
console.log(data);
});
function do_stuff(){
// Access the attributes of data and do stuff
}
function do_more_stuff(){
// Do some more stuff with the data
}
I would probably have do_stuff() execute when the page body loads, and let's say do_more_stuff executes when the user selects something in a dropdown menu. Both need to access the data in products.json. I know there are many examples out there, but I'm just not getting it. How can I re-structure the code to actually work?
I believe you are looking for something like this:
function get_json(cb) {
$.getJSON("products.json", function(data) {
cb(data);
});
}
function cb(data) {
// do stuff here if you want
console.log(data)
}
get_json(cb)
Create a callback function cb (or call it do_stuff if you'd like). Pass a reference to that function to your async function (get_json). When the async operation is complete, call your callback function with the data you received.
I have an helper function that returns an array instead of the conventional db.dbName.find() cursor. How do I code a return array so it reflects as a cursor similar to one generated by a db.dbName.find() that I can use in template?
Find below my helper function:
var arrayTest = Meteor.call('getUserCategoryArray', function(error, results){
if(error){
console.log(error.reason);
} else {
var results1 = results.toString();
var results2 = results1.split(",");
alert("Array content: " +results2);
alert(results2[0]);
alert(results2[1]);
alert(results2[2]);
return results2;
}
})
To explain part of the code: From the top down: The alerts successfully prints out:
Array content: shoes,clothes,watches
shoes
clothes
watches
The alert is just to confirm that results2 is a working array.
Now how do I code the return value/array so that I am able to use it in my template as if it was a cursor returned by a db.dbName.find() query?
Your help is appreciated.
your issue isn't about arrays, it's about synchronous vs asynchronous programming. as #mutdmour mentioned, spacebars can handle an array from a helper just fine.
helpers can get called several times as a template is rendered, so it shouldn't do anything async or have any side effects. your helper is making an async call, so that's one issue right off the bat.
the issue you're seeing is that such a call is async, and a helper needs to be sync. so you'll have trouble getting your helper to work as-is.
in many cases, helpers return the contents of, or a cursor to the contents of, a collection. i don't know your app, but is a publish/subscribe with collection contents a better choice here?
if not, and it has to be the results from a method call, then generally i will:
make the call in the onCreated()
write the results to a reactive var
return the reactive var from the helper
e.g.
Template.Foo.onCreated(function() {
let self = this;
self.clothing = new ReactiveVar();
Meteor.call('getUserCategoryArray', function(error, results) {
if (!error) {
// or whatever you need to do to get the results into an array
self.clothing.set(results);
}
});
});
Template.Foo.helpers({
clothing() {
return Template.instance().clothing.get();
}
});
I want to save the value of data and status in a variable and use it after the closing brackets of jquery GET/POST function.But alert comes only when it is inside .get braces.
$(document).ready(function(){
$.get("demo_test.asp",function(data,status){
v = data;
});
alert("Data:"+v);
});
As Jasper said, your alert is being triggered before the request is complete (async!). So, you have two options:
Do your logic inside the callback:
$.get("demo_test.asp",function(data,status){
v = data;
alert("Data:"+v);
//Process stuff here
});
Or pass the received data onto another function and work with it there
$.get("demo_test.asp",function(data,status){
v = data;
doStuff(v);
});
function doStuff(param) {
console.log(param);
}
You're absolutely correct; the code is working as it should... here's why:
The page loads and starts running code, it then hits the .get command and then keeps running, obviously making it to the 'alert' you have next. Since the .get function is still working on fetching the data before your page makes it to the 'alert' part... there's nothing to prompt.
You might want to string things together after the .get, using deferred objects. Look into: http://api.jquery.com/deferred.always/
This is a way of tacking on another function inside of the one fetching your data, so they depend on each other.
Simple answer, yes, you can store the data in a global variable and access it elsewhere. However, you must wait until it is ready.
The better way to do it is to instead store the jqXHR globally and simply add a done callback to it when you need to access the data.
var reqDemoTest = $.get(...);
//... some time later...
reqDemoTest.done(function(data){
console.log(data);
});
here is my JavaScript code:
var Model =
{
get: function(id)
{
return this.data[id];
},
data: {},
init: function()
{
var self = this;
$.getJSON(urlToServer, function(data)
{
$.each(data, function(i, object)
{
self.data[object.id] = object;
console.log(object.id); // output is: 1, then 2, then 3
});
});
}
};
Model.init();
console.log(Model); // output is the initialized object with children objects 1, 2, 3
console.log(Model.get(1)); // output is undefined
As you can see from the console output i put in the comments, everything works fine until the last line of code. I define a Model and initialize it with some JSON objects provided by the server. But all of a sudden, when i try to access a single child object through the get() method, the Model appears to be undefined.
I just don't get it, please help me out.
Thanks.
Looking at the sample code you used, Model.get(1) will always return undefined.
$.getJSON is an AJAX call that does not necessarily return immediately (known as asynchronous). You will need to use the callback you supplied to $.getJSON to fire off any logic depending on Model.get(1), otherwise it will remain undefined.
$.getJSON is a asynchronous request, you must wait for the response before you call Model.get()
You trying to retrieve object's field "142". I guess you get from json only "1", "2" and "3" id's? If i'm right then get function return to you correct answer because no object field "142" exists.
Can someone tell me why this alert is empty?
var pending_dates = [];
$.getJSON('/ajax/event-json-output.php', function(data) {
$.each(data, function(key, val) {
pending_dates.push({'event_date' : val.event_date});
});
});
alert(pending_dates);
I can't get my head around this. Am I not declaring pending_dates as a global variable, accessible within the each loop? How would one solve this?
Please note that the JSON output is working well. If I would declare pending dates within the getJSON function (and alert within that function), it works, but I need to store the data in an array outside of that getJSON function.
Thanks for your contributions.
EDIT
Thanks to your comments this code is working:
pending_dates = [];
$.getJSON('/ajax/event-json-output.php', function(data) {
$.each(data, function(key, val) {
pending_dates.push({'event_date' : val.event_date});
});
}).success(function() { alert(pending_dates); })
Thanks a lot for your contributions!
I think the problem is $.getJSON is an asynchronous call - it returns immediately and then alert(pending_dates) is invoked.
However, when that happens, the response from the asynchronous call may not have been received, and hence pending_dates may not have been populated.
That is probably why it is empty at the time alert(pending_dates) is called.
Your alert is executing before the JSON call has finished. Remember this JSON it fetched and processed asynchronously, but your alert comes right after it's started. If you want an alert, then you need to put it at the completion of the getJSON call.
$.getJSON is working asynchronously meaning that whatever you have specified in the callback will be executed eventually but there is no guarantee that will happen by the time you reach alert('pending_dates').
You can verify this by moving alert('pending_dates') right after
pending_dates.push() (this would result in one alert being displayed for each item it is retrieving).
You can write a function to start working with the data you're retrieving as soon as it is available:
var pending_dates = [];
$.getJSON('/ajax/event-json-output.php', function(data) {
$.each(data, function(key, val) {
pending_dates.push({'event_date' : val.event_date});
doSomething(val.event_date);
});
});
function doSomething(date) {
// do something with date
// like writing it to the page
// or displaying an alert
}
With this you'll be able to work with all the data you get as it becomes available.
Variables are global by default in Javascript - having var actually introduces scope. Remove that and see if it helps.
It's more likely that the AJAX response isn't returning any data. Can you try pushing just 'foo' onto the array, and see if the alert shows anything different?