0

I have a private async function, _getAssignment, which retrieves data for one id. I also have a public getAssignments function that accepts a list of ids, and ideally does a Promise.all to retrieve the data for all the given ids. However, when calling this function, the Promise.all statement always returns an array that is initially length 0, but is filled in later (similar to this). This is an issue because it prevents me from accessing that data, despite it showing up in the console. The functions are defined as follows:

private async _getAssignment(id: string): Promise<IData | undefined> {
  // retrieve data from firebase
  return {
    id,
    ...docData
  } as IData;
}
public async getAssignments(ids: string[]): Promise<(IData | undefined)[]> {
  // When I add a console.log inside the map's function, it displays the data correctly.
  return await Promise.all(ids.map(async (id) => await this._getAssignments(id));
}

const assignmentInfo = await getAssignments(['id1', 'id2']);

Both of these functions work perfectly fine when I modify the public getAssignment to just execute on one id rather than an array of ids. I am familiar with javascript, however I've never had to mess with promises deeper than using async / await so I'm curious as to what I'm missing here.

I have tried using a .then() block to capture the responses, I have tried making the public function not async, and I have tried making the list of promises separately, then using Promise.all to resolve them. Same outcome, an empty array that gets populated later (according to the browser console). Odd state of the returned array

I have also tried replacing the Promise.all/map solution with a for...of loop that resolves each promise and adds the results to an array, however the array never ends up populated.

let test1: any = []
for (const id of administrationIds) {
  const result = await this._getAssignment(id).then((result) => {
  console.log('resolution', result) // Correct data is printed
  test1.push(result)
  console.log('test1 is now', test1) // Similar outcome to what I have seen with the map.
 })
}
ekelly14
  • 1
  • 1
  • Sounds like you're returning an array that is populated at a later stage. I suspect the problem is buried within the `// retrieve data from firebase` part of your code – Phil Jul 07 '23 at 06:12
  • From the duplicate, see [this answer](https://stackoverflow.com/a/70388625/283366) – Phil Jul 07 '23 at 06:32
  • @Phil, you were correct. I thought I was seeing the resolved promise in the public getAssignments, however I realized that inside the logic `// retrieve data from firebase` I had erroneously tried to use async inside a `forEach`. After restructuring that logic to use `Promise.all(array.map(async (id) => {` everything resolves as intended. Thank you for pointing this out! – ekelly14 Jul 07 '23 at 18:42
  • You should definitely use the method described in the answer I linked. Each individual request to Cloud Firestore chips away at your budget so combining them is in your best interest – Phil Jul 07 '23 at 23:03

0 Answers0