I am using Javascript for a project and this the first time I've used it so I am a bit lost on how to use ascyn function.
I have a firebase/firestore database and I am trying to get a document id from it. I believe below is a good starting point for my code.
for(var i = 0; i < len; i ){
console.log('saving ingredent:', arrayCopy[i].ingredent)
console.log('ingredent id:', getIId(arrayCopy, i))
}
This snippet of code should log the names of the document based on a given array value. Moving forward the getIId is as follows
export async function getIId(arrayCopy, i){
const cIngredent = arrayCopy[i].ingredent
var iID
const ingredientRef = collection(fsdb, 'ingredientInfo')
const q = query(ingredientRef, where("ingredientName", "==", cIngredent))
onSnapshot(q, (snapshot) => {
const ingredientSnap = snapshot.docs
if(ingredientSnap.length != 0){
let ingredents = []
console.log('idCheck onSnapshot 2',ingredientSnap[0].id)
iID = ingredientSnap[0].id
ingredents.push(iID)
console.log('array: ', ingredents)
return ingredents
}else{
console.log('theres no value')
console.log('idCheck onSnapshot else 2',iID)
return iID
}
})
console.log('outside iiD: ', iID)
}
what ends up happening is that
ingredent id: underfined
Comes before the values of the ingredients
idCheck onSnapshot ###############
idCheck onSnapshot 2 ###############
array [###############]
Where ############### is the correct document id. I am not sure how to get the right value from onSnapshot and have it return to as the value from getIId. Once again the value before the return inside onSnapShot is correct.
CodePudding user response:
You need to return something from inside if your getIId
function, there is no magic, if you want to use onSnapshot - then you need to wrap it in a Promise object and return this object with handling reject and resolve (and dont forget to unsubscribe from onSnapshot after that) but if you need to get a result only once - use getDocs
.
Examples: https://firebase.google.com/docs/firestore/query-data/queries
So your code will look like
export async function getIId(arrayCopy, i) {
const cIngredent = arrayCopy[i].ingredent;
const ingredientRef = collection(fsdb, "ingredientInfo");
const q = query(ingredientRef, where("ingredientName", "==", cIngredent));
const getDocsResult = await getDocs(q);
const result = getDocsResult.docs.map((x) => x.id);
if (result.length === 0) {
console.log("No items found");
return undefined;
} else {
console.log("array: ", result);
return result[0]; // we need only 1 item, right?
}
}
also, the function that will use getIId
will need to await
for the result of this function. Or to use getIId(...).then(res => console.log(res));
export async function something(arrayCopy) {
const len = arrayCopy.length;
for (var i = 0; i < len; i ) {
console.log("saving ingredent:", arrayCopy[i].ingredent);
console.log("ingredent id:", await getIId(arrayCopy, i));
}
}
CodePudding user response:
Assuming that onSnapshot and associated callbacks are correct, you just need to add a return to the async function.
return iID
Then the for loop should loop like this in order to make sure everything prints in the right order
for(let i = 0; i < len; i ){
getIId(arrayCopy, i).then((id)=>{
console.log('saving ingredent:', arrayCopy[i].ingredent)
console.log('ingredent id:', id)
}
)
}