Ad
Async/await: Wait For Loop End Before Return Function Result
I have next function:
async getPopular() {
return await tryCatchWithApolloErrorAsync(async () => {
const popular = await adminService
.firestore()
.collection(api.counters)
.doc('companies-by-categories')
.collection('categories')
.get()
let data: Popular[] = []
popular.docs.map(element => {
getCount(element.ref).then(count => {
if (count > 0) {
data.push({
id: parseInt(element.id),
amount: count
})
}
})
})
return data
})
},
But it always return an empty array, even when inside map loop I have some data. How can I make it to wait for popular.docs.map
to finish, before returning the empty data
array?
Ad
Answer
Don't use map
if you're not using its return value. There's no point in having your code create an array you're just immediately going to throw away.
If you want the calls to get the counts to run in parallel, you can use an array of promises from map
with Promise.all
:
async getPopular() {
return await tryCatchWithApolloErrorAsync(async () => {
const popular = await adminService
.firestore()
.collection(api.counters)
.doc('companies-by-categories')
.collection('categories')
.get()
let data: Popular[] = []
await Promise.all(popular.docs.map(async element => { // `async` function
const count = await getCount(element.ref) // returns a promise
if (count > 0) {
data.push({
id: parseInt(element.id),
amount: count
})
}
}))
return data
})
},
Or another way to do that is with filter
:
async getPopular() {
return await tryCatchWithApolloErrorAsync(async () => {
const popular = await adminService
.firestore()
.collection(api.counters)
.doc('companies-by-categories')
.collection('categories')
.get()
let data: Popular[] = await Promise.all(popular.docs.map(async element => ({
id: parseInt(element.id),
count: await getCount(element.ref)
})));
return data.filter(({count}) => count > 0)
})
},
If you want them to run sequentially, use a for-of
loop:
async getPopular() {
return await tryCatchWithApolloErrorAsync(async () => {
const popular = await adminService
.firestore()
.collection(api.counters)
.doc('companies-by-categories')
.collection('categories')
.get()
let data: Popular[] = []
for (const element of popular.docs) {
const count = await getCount(element.ref)
if (count > 0) {
data.push({
id: parseInt(element.id),
amount: count
})
}
}
return data
})
},
Ad
source: stackoverflow.com
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM
Ad