Javascript await in imbricated loop error [duplicate] - javascript

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 );
}
}
}

Related

Async Await Gives Syntax Error Even when code Is correct [duplicate]

This question already has answers here:
ASYNC / AWAIT SyntaxError: await is only valid in async functions and the top level bodies of modules
(5 answers)
Closed 6 months ago.
I have very simple code as below .
Function ls has async keyword and it returns Promise.
But , calling const val = await ls() gives below error.
SyntaxError: await is only valid in async functions and the top level bodies of modules
Can anybody pleasse help me why this error is coming as :
The function ls has async keyword
It also returns a Promise
Further more , using then clause like below , it works fine
ls().then(val => console.log(val)).catch(e => e)
But below code doesn't work
async function ls() {
return new Promise((resolve) => {
resolve('Print Output !!')
});
}
const val = await ls()
console.log(val)
async function ls() {
return new Promise((resolve) => {
resolve('Print Output !!')
});
}
// Way 1
async function test() { //function created for "await ls()"
const val = await ls(); //this await requires async
console.log("Way 1 " + val)
}
test();
// Way 2
(async function() {
const val = await ls();
console.log("Way 2 " + val)
})();

Why i can't pass variables with my function? [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 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()

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
}

Await doesnt wait in async function [duplicate]

This question already has answers here:
Using async/await with a forEach loop
(33 answers)
Closed 2 years ago.
I'm learning async/await but I really don't know what is wrong here. Why is my myArray always an empty when I use await? How can I solve this?
function getFileAsBinary(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsBinaryString(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
};
const preparePhotos = async (photoFiles, myArray) => {
photoFiles.forEach(async (photoFile) => {
const photoBinary = await getFileAsBinary(photoFile);
myArray.push("something")
});
}
// ----------------------------------------------------
const myArray= [];
const photos = [file1,file2];
await preparePhotos(photos,myArray);
console.log(myArray); // getting [] here, why is it empty?
The callbacks passed to the forEach are not synchronous, it can work, but not as expected. When the iteration is done the async function "preparePhotos" will return immediately.
I think you should use a for loop instead.
PD: not sure if this question is a duplicated of: Using async/await with a forEach loop
When you use await inside the forEach loop, you are telling the js engine to "wait" inside the lambda, not the overall function.
If you want to be able to await the preparePhotos function, you will need to some how get "await" out of the lambda.
Start by defining an array of promises
let promises = [];
Then instead of awaiting the promise returned by getFileAsBinary, append it to the list
photoFiles.forEach((photoFile) => {
promises.push(getFileAsBinary(photoFile));
})
You now have a list of promises, and can use Promise.all to await all promises in the list
let myArray = await Promise.all(promises);
Promise#all returns a list of all values resolved by the promises within the original array, so it will return effectively your original "myArray".
Alternatively, use a for of loop (MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of)
for(let elem of photoFiles) {
let binary = await getFileAsBinary(elem);
myArray.push(binary);
}

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();

Categories

Resources