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??
Related
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().
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I am facing small trouble in returning a value from callback function in Node.js, I will try to explain my situation as easy as possible. Consider I have a snippet, which takes URL and hits that url and gives the output:
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
});
I tried to wrap it inside a function and return a value like this:
function doCall(urlToCall) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
Because in my Node.js code, I have a lot of if-else statement where value of urlToCall will be decided, like this:
if(//somecondition) {
urlToCall = //Url1;
} else if(//someother condition) {
urlToCall = //Url2;
} else {
urlToCall = //Url3;
}
The thing is all of the statements inside a urllib.request will remain same, except value of urlToCall. So definitely I need to put those common code inside a function. I tried the same but in doCall will always return me undefined. I tried like this:
response = doCall(urlToCall);
console.log(response) //Prints undefined
But if I print value inside doCall() it prints perfectly, but it will always return undefined. As per my research I came to know that we cannot return values from callback functions! (is it true)? If yes, can anyone advice me how to handle this situation, as I want to prevent duplicate code in every if-else blocks.
Its undefined because, console.log(response) runs before doCall(urlToCall); is finished. You have to pass in a callback function aswell, that runs when your request is done.
First, your function. Pass it a callback:
function doCall(urlToCall, callback) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return callback(finalData);
});
}
Now:
var urlToCall = "http://myUrlToCall";
doCall(urlToCall, function(response){
// Here you have access to your variable
console.log(response);
})
#Rodrigo, posted a good resource in the comments. Read about callbacks in node and how they work. Remember, it is asynchronous code.
I am facing small trouble in returning a value from callback function in Node.js
This is not a "small trouble", it is actually impossible to "return" a value in the traditional sense from an asynchronous function.
Since you cannot "return the value" you must call the function that will need the value once you have it. #display_name already answered your question, but I just wanted to point out that the return in doCall is not returning the value in the traditional way. You could write doCall as follow:
function doCall(urlToCall, callback) {
urllib.request(urlToCall, { wd: 'nodejs' }, function (err, data, response) {
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
// call the function that needs the value
callback(finalData);
// we are done
return;
});
}
Line callback(finalData); is what calls the function that needs the value that you got from the async function. But be aware that the return statement is used to indicate that the function ends here, but it does not mean that the value is returned to the caller (the caller already moved on.)
Example code for node.js - async function to sync function:
var deasync = require('deasync');
function syncFunc()
{
var ret = null;
asyncFunc(function(err, result){
ret = {err : err, result : result}
});
while((ret == null))
{
deasync.runLoopOnce();
}
return (ret.err || ret.result);
}
If what you want is to get your code working without modifying too much. You can try this solution which gets rid of callbacks and keeps the same code workflow:
Given that you are using Node.js, you can use co and co-request to achieve the same goal without callback concerns.
Basically, you can do something like this:
function doCall(urlToCall) {
return co(function *(){
var response = yield urllib.request(urlToCall, { wd: 'nodejs' }); // This is co-request.
var statusCode = response.statusCode;
finalData = getResponseJson(statusCode, data.toString());
return finalData;
});
}
Then,
var response = yield doCall(urlToCall); // "yield" garuantees the callback finished.
console.log(response) // The response will not be undefined anymore.
By doing this, we wait until the callback function finishes, then get the value from it. Somehow, it solves your problem.
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().
I am using the below json call in my javascript method
function go123(){
var cityName = "";
var temp = $.getJSON("https://abc.in/api/city?callback=?", args,function (data) {
if (data.properties.city != null){
cityName = data.properties.city;
check = true;
} else {
cityName = "NaN"
}
}); // end of my Json Call.
// my validation is done below
if(cityName != "NaN"){
return false;
} else {
// here I except the cityName to not be "" but be some value which is set as :cityName = data.properties.city;
return true;
}
} // end of my function
Now what problem I am facing is that before my Json call is compelete the next set of statements ( in the code below the line "// my validation is done below " ) is already executed.
I want to get the values set in my json call (cityName) and only once when the call is completed then only I want the next set of statements to be executed.
Please help me on this. Any advice/ideas/suggestions will be highly appreciated ! Thanks.
The function you passed into $.getJSON() is the callback run when the function completes successfully. All else being equal, stick the "rest of it" inside that method. If you can't do so, what you're after is called a jQuery Deferred. See http://www.erichynds.com/jquery/using-deferreds-in-jquery/ and http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/ for code that looks like so:
var req = $.getJSON('blah', 'de', 'blah');
req.success(function(response){
// The request is done, and we can do something else
});
AJAX calls are asyncrhonous. They don't wait for the reply. They operate in the background and execute the code that follows it immediately after the call. Therefore, the data received in getJSON is not yet there when the operations below it are executed.
You can put the operations you want in the callback so that they get executed when the data is revceived:
function go123(callback){
var temp = $.getJSON("https://abc.in/api/city?callback=?", args,function (data) {
//execute the callback, passing it the data
callback(data);
});
}
//when you call go123, it get's back the result:
function goBefore123(){
//get our JSON
go123(function(data){
//when we get our data, evaluate
if (data.properties.city != null){
cityName = data.properties.city;
check = true;
alert('executed after returned');
afterCall();
} else {
cityName = "NaN"
}
});
alert('i am executed before anything else');
}
function afterCall(){
alert('im also executed after');
}
Calling an external url will take too much time, wait for the result
Check below
var jqxhr = $.getJSON("example.json", function() {
alert("success");
})
.success(function() { alert("second success"); })
.error(function() { alert("error"); })
.complete(function() { alert("complete"); });
http://api.jquery.com/jQuery.getJSON/
.success
http://api.jquery.com/jQuery.getJSON/
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?