This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have a question regarding setting 'public' variable in JavaScript. Here is my code:
var storeKey;
firebase.database().ref('stores').orderByChild('storeAddress').equalTo('Blk 167').once('value', function(snapshot) {
var storeData = snapshot.val();
if (storeData){
console.log('exists');
}else{
storeKey = firebase.database().ref('stores').push({
storeName : "store1",
storeAddress : "Blk 167"
}).getKey();
//console.log("STORE " + storeKey);
}
});
console.log("STORE " + storeKey);
I am checking if the address exists before adding new record into Firebase. However, if I put the console.log at the last line, I get undefined. It only returns a value if I print it out inside the else statement.
I wanted to separate the storeKey out before I need that data in other places and I don't want my code to be nested inside the else statement. Any idea how to achieve this?
Your function accepts a callback, the console.log is called before the callback, that's why its undefined One way to "solve" it is using promises. e.g.
const deferred = q.defer();
firebase.database().ref('stores').orderByChild('storeAddress').equalTo('Blk 167').once('value', function(snapshot) {
var storeData = snapshot.val();
if (storeData){
console.log('exists');
}else{
storeKey = firebase.database().ref('stores').push({
storeName : "store1",
storeAddress : "Blk 167"
}).getKey();
deferred.resolve(storeKey);
}
});
deferred.then(console.log)
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Using async/await with a forEach loop
(33 answers)
Closed 1 year ago.
I am trying to build a simple crypto portfolio in nodejs by fetching prices from coingecko API. I set up a simple mongodb with all assets and I am parsing through the db and fetching each price. The fetch works as I can console.log the results however I cannot seem to be able to store the prices in a variable that I can call outside the fetch function. Thus, I cannot pass the prices to my ejs file. I am quite new to js (coming from python), and it seems that I am missing someting on how to handle api results, here is my code:
app.get('/dashboard', (req, res) => {
Holdings.find ((err, allHoldings) => {
if (err) {
res.type('html').status(500);
res.send('Error: ' + err);
}
else if (allHoldings.length == 0) {
res.type('html').status(200);
res.send('You have no holdings');
}
else {
var priceList = {};
allHoldings.forEach(async coin => {
coin = coin.asset;
const uri = 'https://api.coingecko.com/api/v3/simple/price?ids=' + coin + '&vs_currencies=usd&include_market_cap=false&include_24hr_vol=false&//include_24hr_change=false&//include_last_updated_at=false';
const fetch_price = await fetch(uri);
const json = await fetch_price.json()
const price = json[coin]['usd'];
priceList[coin] = price;
priceList.save;
console.log(priceList);
return priceList;
});
console.log(priceList);
res.render('dashboard', { holdings : allHoldings})
}
});
});
As you can see I set a priceList object before performing the API fetch and then I try to push the pair {coin : price} to that object. The first console.log works fine, however the second one only logs an empty object.
Any idea ?
Thanks
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
Long story short. I'm trying to learn javascript. And i've been googling for about 4 hours straight right now. And i cant find the answer to my current problem, so i'm assuming i'm looking at this the wrong way.
I'm trying to create a slackbot. The bot is connected, and can look for messages so that part is working.
I've (tried to)create(ed) a function that gets the userID of everynew message based on the name i set in. In my mind this function returns the userID, and that i can later down the code check if userID is in message.text, if it is do something.
I'm assuming it has something to do with that .then function. Can i even return data from that .then function? or can u just use that data inside of that function.
I have several return functions as i was trying to just return it from wherever u could.
function getuserid(botname){
var id = ''
var getbotid = bot.getUsers();
getbotid.then(function(value){
for(var i=0;i<value.members.length;i++){
if(value.members[i].name == botname){
id = value.members[i].id
console.log(id);//this logs what i want.
return id
}
} return id
})
return id
}
var botid = getuserid('jokester');
console.log(botid);
I'm not sure but in my experience, if you return getbotid() then actually you return a promise and you can use it .
function getuserid(botname){
var id = ''
//************Here I return getbotid
return bot.getUsers().then(function(value){
for(var i=0;i<value.members.length;i++){
if(value.members[i].name == botname){
id = value.members[i].id
console.log(id);//this logs what i want.
return id
}
} return id
})
return id
}
//Now you can use it
getuserid('jokester').then(id => console.log(botid));
This question already has answers here:
How do I access previous promise results in a .then() chain?
(17 answers)
Closed 5 years ago.
A bit new to javascript.
Been dealing with promises, however ran into a problem i dont know how to approach.
How can i pass a value into the next promise resolve?
Here's my code
bot.on('ask.add_account_password', (msg) => {
let username = users[msg.from.id].username;
let password = msg.text;
var accounts = require('./inc/account.js');
accounts.login_account(username,password).then(function(data){
var account = data.params;
console.log(account);
return accounts.store(msg.from.id,username,password,account.followerCount);
}).then(function(data){
let caption = "Your account "+account.username+"("+account.fullName+")has been added\n";
return bot.sendPhoto(msg.from.id, account.picture, {caption:caption});
})
.catch(function(error){
console.log(error);
add_account(msg,error.name);
});
});
On the line where i create the caption variable, i'm trying to access the account object created in the block before it(var account = data.params) but i get a reference error saying its not defined. Now i can easily bypass this by just sending the entire object into the accounts.store function and have it resolve the object when done, but that just seems like a dirty workaround to a bigger problem. Is there a cleaner way to do this?
You can create variable (and set it in promise) in main function or you can return this as result of first promise instead of result from function store
account is undefined at second .then(), use data to reference the Promise value accounts.store returned from previous .then()
.then(function(data) {
// `data` : `accounts.store` returned from previous `.then()`
let caption = "Your account " + data.username
+ "(" + data.fullName + ")has been added\n";
return bot.sendPhoto(msg.from.id, data.picture, {caption:caption});
})
You can pass it in an array and use destructuring in the arguments to unpack the array.
accounts.login_account(username,password).then(function(data){
var account = data.params;
console.log(account);
return [account, accounts.store(msg.from.id,username,password,account.followerCount)];
}).then(function([account, data]){
let caption = "Your account "+account.username+"("+account.fullName+")has been added\n";
return bot.sendPhoto(msg.from.id, account.picture, {caption:caption});
})
You don't actually appear to be using data, so you could just return account after calling store
This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 6 years ago.
I have a schema which saves Cat information. I then want to create an array of all the cat_urls, however when I call the array outside of the dbs call, the array is empty
var cat_urls = [];
Cat.find(function (err, data) {
var stringify = JSON.stringify(data)
content = JSON.parse(stringify);
content.forEach(function (result) {
cat_urls.push(result.cat_url);
})
console.log(cat_urls, 'here')
})
console.log(cat_urls, 'here not working') // I want cat_urls to also be populated here
So Inside the Cat.find() call cat_urls has values like this:
[ 'www.hello.co.uk', 'www.testing.co.uk' ] 'here'
But outside cat_urls = []
I guess this is to do with the fact that node js does not run in a specific order, but how can I solve this issue?
I think it's working but your find function returns a promise that resolves asynchronously.
Try:
var cat_urls = [];
Cat.find(function (err, data) {
var stringify = JSON.stringify(data)
content = JSON.parse(stringify);
content.forEach(function (result) {
cat_urls.push(result.cat_url);
})
console.log(cat_urls, 'here')
}).then(function(){
// Promise has completed, now this console log will trigger only after the cat's names are pushed.
console.log(cat_urls);
})
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 8 years ago.
can you please tell me what i am doing wrong here. i know its simple problem but took whole day for this.
all i was trying to do was adding a value to array called messages from json file.
function get_message(params) {
var messages = ["hello", "bb"]; // i have manually assigned the value here for testing purpose
$.getJSON("messages.json", function( json ) {
var test="JSON Data: " + json.login.loginsuccess.excited.en[0] ; // this is working fine. just retrieving 1 value for testing
console.log(test); // it shows the output get from json file. this line is also fine
messages.push(test);// here is the problem. why i am not being able to add value to this array messages?
});
alert(messages[2]);// it gives me out put undefined
var index = Math.floor(Math.random() * messages.length);
return messages[index];
}
thanks
It's because the AJAX call is asynchronous, so the alert() line is firing before the data is pushed to the messages array. Try moving your code to show the alert inside the callback function.
getJson is asynchronous, so you need to ensure that you're not checking the messages array too soon. You should probably use a callback to get the information you need.
function get_message(params, callback) {
var messages = ["hello", "bb"];
$.getJSON("messages.json", function( json ) {
var test="JSON Data: " + json.login.loginsuccess.excited.en[0];
console.log(test);
messages.push(test);
alert(messages[2]);
var index = Math.floor(Math.random() * messages.length);
callback(messages[index]);
});
}
And use like:
get_message(params, function (data) {
console.log(data);
});