Why i can't pass variables with my function? [duplicate] - javascript

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 1 year ago.
I have this code in my react native app that is using firebase :
let bestTutors = [];
const getBestTutors = async () => {
const snapshot = await getDoc(docRef);
bestTutors = snapshot.data().list;
}
getBestTutors();
console.log(bestTutors);
But when i run it it only console logs "Array[ ]", I've tried to using .then( ) and all kind other stuff that doesn't make sense for me, idk if there's a wey to use it without the await or How can i pass the data to the variable :( ?

Look at my comments
Your Code 1
let bestTutors = [];
const getBestTutors = async () => {
const snapshot = await getDoc(docRef);
bestTutors = snapshot.data().list;
}
getBestTutors(); // Asynchronous function
console.log(bestTutors); // this is called before getBestTutors() returns the data. So console.log(bestTutors) return de default value: []
The new code
let bestTutors = [];
const getBestTutors = async () => {
const snapshot = await getDoc(docRef);
bestTutors = snapshot.data().list;
}
await getBestTutors(); // Wait until getBestTutors() has finished and then Next.
console.log(bestTutors);

call function with await. Like this one
await getBestTutors()

Related

Javascript await in imbricated loop error [duplicate]

This question already has answers here:
WHy am I getting a SyntaxError: Unexpected identifier in forEach with await?
(1 answer)
How to use async/await syntax with forEach loop in Javascript?
(4 answers)
SyntaxError when calling async await in Loop
(1 answer)
Using async/await with a forEach loop
(33 answers)
Closed last year.
I'm trying to understand to to imbricate loops in javascript and call an imported async function from an async script and I get an error. It seems like ReadinglogManager.getReadingLogForAPeriod cannot be call with await?
Main code:
var myfunction = async function(req, res, next){
students.forEach(function(s) {
dateobj.forEach(function(d) {
console.log('Date: '+d.toString())
let st= new Date();
const rl = await ReadinglogManager.getReadingLogForAPeriod(st,s.uid );
});
});
}
From ReadinglogManager:
var getReadingLogForAPeriod = async function(start_date, student_uid){
let db = DatabaseManager.fs.firestore();
let dataset = [];
let snapshot = await db.collection('ReadingLog').where('date', '>=', start_date).where('student_uid', '=', student_uid).get();
// dataset = await DatabaseManager.snapshot_to_resultset(snapshot);
await snapshot.forEach(doc => {
let tdoc=doc.data();
tdoc.uid=doc.id;
console.log("DOC: "+JSON.stringify(tdoc));
dataset.push(tdoc);
});
return Promise.resolve(dataset);
}
Thanks
As await can only be used within an async function and the callback function (the function(d) {} part) is not async so such using will result in an error.
Also changing it to async function(d) {} does not solve the problem neither. Because forEach does not expect its callback to be an async function and does not await its asynchronous execution.
So for such cases you should use plain loop instead of forEach, like:
var myfunction = async function(req, res, next){
for(let n = 0;i<students.length;++i){
let s = students[n];
for(let i = 0;i<dateobj.length;++i){
let d = dateobj[i];
console.log('Date: '+d.toString())
let st= new Date();
const rl = await ReadinglogManager.getReadingLogForAPeriod(st,s.uid );
}
}
}

function is async but getting error that await keyword cannot be used [duplicate]

This question already has answers here:
Using async/await with a forEach loop
(33 answers)
Closed 1 year ago.
The code below is causing the following console error: Can not use keyword 'await' outside an async function.
async getData() {
// an await occurs here for something else
const menu = {
'pounds': 'DemandModification',
'combination': 'DemandCombinationOverride'
};
const overridesWithStaleBuckets = {};
Object.entries(menu).forEach(o => {
const overrideType = o[0];
const api = o[1];
const overrides = await this.$http.execute('read', api);
overridesWithStaleBuckets[overrideType] = overridesWithStaleBuckets[overrideType] || {};
overridesWithStaleBuckets[overrideType] = overrides;
});
// non problematic logic omitted
return overridesWithStaleBuckets;
}
The console specifically calls out the await in this line as being the issue:
const overrides = await this.$http.execute('read', api);
Why is this error occurring when the function is async?
You cannot use await in a forEach loop, you will need a normal for loop for this.
let entries = Object.entries(menu);
for (let entry of entries) {
//Do things
}

Async - await not executing callback in a for loop [duplicate]

This question already has answers here:
How do I convert an existing callback API to promises?
(24 answers)
Closed 2 years ago.
I have used the async function and waiting for one API to hit and display its current file name which got uploaded then increase the counter I and go for the next file.
ISSUE: The async and await is working fine but the callbacks are called after all the requests have been made.
How can I hit the API and get its name printed then go for another file to hit the API?
PS: I can't change callback to promise, it's a defined structure in my organization as of now.
Code:
uploadCallback = () => {
console.log(currentFile)
}
const loop = async() => {
for (let i = 0; i < this.state.fln.length; i++) {
currentFile = obj.fln;
await uploadAPI(obj, this.uploadCallback);
console.log('currentFile:', i, currentFile);
}
};
You could try something like this:
uploadCallback = () => {
console.log(currentFile)
}
const loop = async() => {
for (let i = 0; i < this.state.fln.length; i++) {
currentFile = obj.fln;
const res = await uploadAPI(obj);
this.uploadCallback(res);
console.log('currentFile:', i, currentFile);
}
};
This will make sure that the callback is called only after uploadAPI finishes.
You'll need to integrate promises. Here's an example with the Pokemon API...
let thisstateflnlength = 5
const getAPI = (counter = 0) => {
if (counter <= thisstateflnlength) {
fetch("https://pokeapi.co/api/v2/pokemon/ditto").then(response => response.json()).then(data =>{
console.log(data.forms[0])
console.log(counter)
}).then(data => getAPI(counter+1))
}
}
getAPI()
The counter logs from 0-5 and each API call is executed asynchronously.

How to get .map to complete before returning result in javascript? [duplicate]

This question already has answers here:
Use async await with Array.map
(9 answers)
Closed 2 years ago.
I'm struggling with using .map and await. How do I get the below to wait until the map has completed?
export async function buildDeviceArray(userIdList){ //userIdList is an array of ids
await userIdList.map(myFunction2)
return deviceArray1 // returns straight away, rather than waiting for the .map to complete
async function myFunction2(item) {
let user = await wixData.get("OurUsers", item)
let device = await wixData.get("Devices", user.deviceDefault)
let output = { "label": device.deviceReference, "value": user.deviceDefault }
if (user.deviceDefault) deviceArray1.push(output)
console.log(deviceArray1);
return
}
This is an example of how you could use .map with an async callback function.
var originalArray = [1,2,3,4];
async function multiplyBy2(x) {
await new Promise(r => setTimeout(r, 5000)); // half second
return 2*x;
}
async function run() {
var promiseArray = originalArray.map(multiplyBy2)
var answerArray = await Promise.all(promiseArray);
console.log(answerArray);
}
run();

Javascript why return empty array [duplicate]

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 2 years ago.
I know Js is async but how to prevent my callback from returning an empty array ?
Here is my code :
function getPicturesArray(nbr,callback){
var avatarArr = [];
for(var i =0; i<nbr ; ++i){
request("https://randomuser.me/api/",{json: true},(err,response,body)=> {
avatarArr.push(body.results[0].picture.large);
});
}
callback(avatarArr);
}
getPicturesArray(12, (e)=>{
console.log(e);
});
console.log('here');
And the sout is:
[]
here
I'm mocking the calls with a public service for demonstration purposes, but the key point here is the asynchronous nature of HTTP requests.
When you invoke callback(avatarArr);, your for loop IS done but the (in this case 12) requests you sent are not, so avatarArr does not have any items yet.
Notice async before function getPicturesArray, and await before fetch
await tells the execution to wait for the fetch call to finish
You MUST check out async/await.
async function getPicturesArray(nbr,callback){
var avatarArr = [];
console.log('loading...');
for(var i =0; i<nbr ; ++i){
const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${i+1}`);
const json = await response.json();
avatarArr.push(json.title);
}
console.log('done loading...');
callback(avatarArr);
}
getPicturesArray(12, (e)=>{
console.log(e);
});
console.log('see how this is executed before done loading...');
Don`t use callbacks. Use Promises or async/await.
getUserPic = async () => {
const url = 'https://randomuser.me/api/'
const response = await fetch(url)
const users = await response.json()
return users.results[0].picture.large
}
;(async () => {
const userAvatars = []
for (let i = 0; i < 12; i++) {
userAvatars.push(await getUserPic())
}
console.log(userAvatars)
})()
Also try to use this.
In this case I advice you to use Set instead of Array to exclude duplicate items.
getUserPic = async () => {
const url = 'https://randomuser.me/api/'
const response = await fetch(url)
const users = await response.json()
return users.results[0].picture.large
}
getMultipleUserPics = async limit => {
const userAvatars = new Set()
while (userAvatars.size != limit) {
userAvatars.add(await getUserPic())
}
return userAvatars
}
;(async () => {
const userPics = await getMultipleUserPics(5)
console.log(userPics)
})()

Categories

Resources