I'm stuck on an issue where I'm parsing the results from an API in getSubscriptions()
. This calls getUserSubs()
which returns the following object:
When I call on subscriptions
I get the expected array console (See "Works") snippet.
But when I try to iterate on the array subscriptions
(See "Doesn't work"), then the contents of the function are not even called.
userSubs() is called for API data
async function getUserSubs(userId) {
const ref = collection(db, "users", userId, "subscriptions")
let subList = []
try {
const subIds = await getDocs(ref)
subIds.forEach(subRef => {
const docRef = subRef.data()
getDocData(docRef.product).then(product => {
subList.push(product)
})
})
return subList
} catch (e) {
console.error("Error in getting subscriptions: ", e)
return []
}
}
Works
function getSubscriptions(userId) {
getUserSubs(userId).then(subscriptions => {
console.log(subscriptions) // Works as intended
}
}
Doesn't work
function getSubscriptions(userId) {
getUserSubs(userId).then(subscriptions => {
subscriptions.forEach(x => {
console.log(x) // ISSUE: This isn't called
})
}
Also doesn't work
let a = []
getUserSubs(userId).then(subscriptions => {
subscriptions.forEach(x => a.push(x))
})
console.log(a)
I know there are similar questions asked but after reading them I'm still not able to resolve my issue.
Similar issues:
CodePudding user response:
getUserSubs(userId).then(subscriptions => { console.log(subscriptions) // Works as intended }
No it doesn't. It only appears so because you are inspecting the live array that was mutated after it has been logged to the console.
Also doesn't work:
let a = [] getUserSubs(userId).then(subscriptions => { subscriptions.forEach(x => a.push(x)) }) console.log(a)
Yes, for rather obvious reasons: the array is logged before you fill it. It would need to be either
getUserSubs(userId).then(subscriptions => {
let a = []
subscriptions.forEach(x => a.push(x))
console.log(a)
})
or
let a = []
const subscriptions = await getUserSubs(userId)
subscriptions.forEach(x => a.push(x))
console.log(a)
But none of these will solve your core problem: getUserSubs
returns an empty array before it gets filled, in the lines
subIds.forEach(subRef => {
const docRef = subRef.data()
getDocData(docRef.product).then(product => {
subList.push(product)
})
})
return subList
you never wait for the getDocData
promise. If you change that to
let subList = []
for (const subRef of subIds) {
const docRef = subRef.data()
const product = await getDocData(docRef.product)
subList.push(product)
}
return subList
or just
return Promise.all(subIds.map(subRef => {
const docRef = subRef.data()
return getDocData(docRef.product)
})
it would work, as described in the question you already found.
(This might still not work. subIds
looks suspiciously like a firebase snapshot, which is not an array and can neither be iterated nor does it have a .map
method. In that case, you'll need to use forEach
push
manually).
CodePudding user response:
Honestly I wouldn't use the forEach() method. I think all you need to do to fix this is iterate over the results in a normal for loop.
for(let subscription of subscriptions) {
console.log(subscription);
}
OR
for(let index in subscriptions) {
console.log(subscriptions[index]);
}
If this doesn't do the trick, I'll open up a sandbox and look more in depth.