Using $.getJSON on a global variable doesn't seem to work - javascript

I'm extremely new to Javascript and jQuery and I'm not quite understanding why the following code doesn't work
var collectibleCards = [];
$(document).ready(function () {
$.getJSON('AllSets.json', function (json) {
$.each(json, function(sets, cards) {
$.each(cards, function(element, card) {
if(card['collectible'] && card['type'] !== "Hero") {
collectibleCards.push(new Card(card));
}
});
});
});
});
console.log(collectibleCards.length); // prints 0
Why does collectibleCards not get any elements added? I've even tried just pushing numbers and still get nothing added to the array.

It's because getJSON is async operation and result of the callback will appear after some time, when browser get response from the server (or, in your case, from a json file).
So lets see:
// You create a variable
var collectibleCards = [];
// You start your ajax request by doing getJSON
$.getJson('AllSets.json', function () { // This code will evaluate AFTER browser get response from the file });
// You logged your variable and it still an emtpy array because ajax doesn't get a response yet
console.log(collectibleCards.length); // prints 0

You are trying to access the variable before its getting updated in success callback of getJSON, thats why you are getting it of length 0, If you want to access it outside of callback then use $.ajax and make it synchronous call else manipulate on collectibleCards in callback function itself not outside.
var collectibleCards = [];
$(document).ready(function () {
$.getJSON('AllSets.json', function (json) {
$.each(json, function(sets, cards) {
$.each(cards, function(element, card) {
if(card['collectible'] && card['type'] !== "Hero") {
collectibleCards.push(new Card(card));
}
});
});
console.log(collectibleCards.length); // print correct length
});
});
Also see
Calling Ajax and returning response

Related

function reading JSON data not passing to variables

I am creating a function to read different JSON files. The problem is when I try to pass the array.
I keep getting 'undefined' once I am back to my primary function.
Reading the file works but when I try to use the variable I get 'undefined'.
I could use some help. thanks.
This is the file I read 'data.json':
[
{
"code":"10000",
"name":"new",
"filter":"Office",
"label":"NEW"
},
{
"code":"10001",
"name":"classic",
"filter":"Office",
"label":"CLASSIC"
},
{
"code":"10002",
"name":"old",
"filter":"Office",
"label":"OLD"
}
]
Here's my code:
function readfile(myfile) {
var mydata;
$.get(myfile, function (data) {
mydata = JSON.parse(data);
console.log(mydata); // result ok
});
console.log(mydata); // undefined
return (mydata); // return 'undefined'
}
var content = readfile('data.json'); //should be an array
console.log(content); // undefined
You're almost there!
The jQuery $.get() method is an asynchronous call. That means that instead of making the request to get myfile, waiting until it is complete, and then continuing from there, the code will make the request and continue on while the request is done in the background.
There are two things you can do here.
The first thing you can do is simply move your logic inside the callback function like so
$.get(myfile, function (data) {
mydata = JSON.parse(data);
console.log(mydata); // do whatever you need
});
However, if you want to continue using the readfile method, you can make the $.get request synchronous, wait for the response, then return from it.
Like so:
function readfile(myfile) {
var mydata;
$.get({
url: myfile,
async: false,
success: function(data) {
mydata = data;
}
});
return mydata;
}
Get is asynchronous meaning that it will not execute in the order it is written.
$.get(myfile, function (data) {
mydata = JSON.parse(data);
console.log(mydata); // result ok
});
This is why
console.log(mydata); // undefined
return (mydata);
is undefined, because the values are not actually set from get().

how to get data outside javascript function

im wondering if i can get some help here, im not a skilled coder by far, but im trying to retrieve results outside the function and the result in log im getting is Undefined
var pricecrex;
getDataFromAPI("https://api.crex24.com/CryptoExchangeService/BotPublic/ReturnTicker?request=[NamePairs=BTC_WAGE]",
true,
function(data){
var resultcrex = JSON.parse(data);
if (resultcrex !== "undefined") {
if (resultcrex) {
var pricecrex = resultcrex.Tickers[0].Last
}
else {
msg.reply("0")
}
}
}
);
console.log(pricecrex);
It is because Ajax requests are async. console.log() gets executed before response is received from request, and thus before setting value in pricecrex. So you were getting undefined.
var pricecrex;
getDataFromAPI("https://api.crex24.com/CryptoExchangeService/BotPublic/ReturnTicker?request=[NamePairs=BTC_WAGE]",
true, function(data) {
var resultcrex = JSON.parse(data);
if (resultcrex !== "undefined") {
if (resultcrex) {
pricecrex = resultcrex.Tickers[0].Last;
print(pricecrex);
}
else {
msg.reply("0")
}
}
}
);
function print(data) {
console.log(data);
}
The nature of Javascript is continue running code once an asynchronous function has been started. So you run getDataFromAPI(), and then while that's running, the interpreter goes to the next piece of code, which is your console.log(pricecrex).
So you can either run the console.log(pricecrex) directly in the callback, function(data){}, or to keep things cleaner, wrap your console.log() within a function and call that function from within your callback.
Example:
let someVar;
someAsync('someurl.com', (data) =>{
someVar = data;
callTheConsole()
})
function callTheConsole(){
console.log(someVar)
}
Instead of assigning the value to the variable. Pass it to another function. Thus the value passed to another function is not 'undefined'.
function validation(pricecrex){
console.log(pricecrex);
}
getDataFromAPI("https://api.crex24.com/CryptoExchangeService/BotPublic/ReturnTicker?request=[NamePairs=BTC_WAGE]",
true,
function(data){
var resultcrex = JSON.parse(data);
if (resultcrex !== "undefined") {
if (resultcrex) {
var pricecrex = resultcrex.Tickers[0].Last;
validation(pricecrex);
}
else {
msg.reply("0")
}
}
}
);
For more information, check out the below link. Detailed information with examples is available.
How to return the response from an asynchronous call??

Returning a value from 'success' block in JS (Azure Mobile Service)

I have a rather simple getUser method that I'm having some trouble with. I am not deeply familiar with scopes and such in JS so this is giving me a head ache. Basically I want to fetch an object from the database and return it to the calling method:
function getUser(uid)
{
var result = null;
var userTable = tables.getTable('Users');
userTable.where({
userId: uid
}).read({
success: function (results) {
if (results.length > 0) {
result = results[0];
console.log('userid'+result.id);
}
}
});
console.log('userid-'+result.id); // undefined!!
return result;
}
Also, returning from inside the success doesn't return from getUser, but just the function defined inside. I tried "result = function(results)" as well but it stores the defined function and not the return value.
How am I supposed to do this?
I found a solution to this elsewhere. In practice (to the best of my understanding), it is not possible to do this within a JavaScript with asynchronous functions. What you need to do is create a recursion instead from inside the success handler.
Because the call to the database is asynchronous, your last two lines are executed (and hence result is undefined) before the call the database actually finishes. So you need to handle everything inside your success callback. Or, if your getUser() func is a helper, you could structure your code (without recursion) like this with a callback:
function insertOrWhateverCallingMethod()
{
var uid = 'blah';
getUser(uid,function(user) {
// Do something with the user object
});
}
function getUser(uid,callback)
{
var result = null;
var userTable = tables.getTable('Users');
userTable.where({
userId: uid
}).read({
success: function (results) {
if (results.length > 0) {
result = results[0];
console.log('userid'+result.id);
callback(result);
}
}
});
callback(null);
}
The code above assumes you're in a table script, where the tables object is available - if it's not you can pass it as a parameter to getUser().

Jquery get text file and return the value to other function

Can any one help me what im wrong in
function separateerror()
{
var jqxhr = $.get("/errormsg.txt", function(data) {
line = data;
array = line.split(',');
getmsg=array[0];
})
return getmsg;
}
i need to return "getmsg" to another function, but its not working, where as if i add alert inbetween
function separateerror()
{
var jqxhr = $.get("/errormsg.txt", function(data) {
line = data;
array = line.split(',');
getmsg=array[0];
})
//alert(getmsg)
return getmsg;
}
the value returns, what wrong im doing in code?
$.get is an async call and what happens is that if you add an alert in between, you give time for the async call to finish and then your value is already set by the time the separateerror function finishes. Otherwise, the separateerror function returns before the $.get call finishes and then your getmsg is probably still a null value.
While working with async calls you should not use this simple model of calling functions and expecting theirs values in return, you should use callback functions to accomplish that the right way.
EDIT:
Also, you should handle the $.get error callback, in case something happens and you can not load the txt file.
function separateerror()
{
var jqxhr = $.get("/errormsg.txt", function(data) {
line = data;
array = line.split(',');
getmsg=array[0];
dosomething(getmsg);
})
.error(function() { alert("error"); });
}
function dosomething(msg) { ... }
Insert that to the top of your script. That /should/ fix it.
$.ajaxSetup({
async: false
});

Getting undefined via ajax JSON

when I check the log from Console using chrome browser, I keep getting sideType is undefined. It is not returning data to sideType variable.
when I put console.log(sideType); in the sideGroupData() function - it work fine without problem.
Code:
function sideGroupData(GroupID) {
$.getJSON("group_data.php",{GroupID:GroupID}, function(j){
return j;
});
}
function reloadProduct(productID) {
$.post("product.php", { productID:productID }, function(data) {
var sideType = sideGroupData(123);
console.log(sideType);
});
}
reloadProduct(999);
It's because you're running your call in a closure. The ajax call is being made asynchronously, which means that your code continues moving even though you're making an ajax call:
function setVar () {
var retVal = 1;
$.ajax(..., function(data){
retVal = data; //retVal does NOT equal data yet, it's still waiting
});
return retVal; //will return 1 every time because code doesn't wait for ajax
}
var someVar = setVar(); // will be 1
If you want to return that value, include a callback function to run when the data is returned, and run it with the data supplied, like so:
function sideGroupData(GroupID, callback){
$.getJSON('group_data.php', {GroupID: GroupID}, callback);
}
function reloadProduct(productID) {
$.post("product.php", { productID:productID }, function(data) {
sideGroupData(123, function(sideType){
console.log(sideType);
});
});
}
or, just make the call inside the function itself:
function reloadProduct(productID, groupId) {
var prod, sideType;
$.post("product.php", { productID:productID }, function(data) {
prod = data;
$.getJSON('group_data.php', {GroupID: groupId}, function(json){
sideType = json;
// you now have access to both 'prod' and 'sideType', do work here
});
});
}
the sidegroupdata() function call will return immediately - it'll trigger the ajax request and keep on executing. That means sideType is being assigned a null value, because sideGroupData doesn't actually explicitly return anything after the ajax call section.
Is there any reason you're doing an ajax request WITHIN an ajax request? Wouldn't it make more sense to modify the product.php page to return a data structure containing both that product ID AND the 'sidegroupdata' included in a single response?

Categories

Resources