Looping issue with ForEach in Typscript with Firebase Functions

While browsing through various questions on this topic, I've noticed that the specific answers provided don't quite fit my situation. My query involves converting a Google Firebase RTB datasnapshot into an array of custom objects, each representing a child node and its sub children. However, I'm facing challenges with post-processing the data due to the inability to call await within a foreach loop.

After some research, I came across a solution on StackOverflow. The approach involves creating a separate function to parse the data and store promises in their own array, which is then awaited from the top level:

export async function unpack_snap(snap: any): Promise<(CustomObject[] | null)>{
    const toWait: any[] = [];
    console.log(JSON.stringify(snap)); 

    await snap.forEach(async obj => {  
        toWait.push(obj_from_snap((obj)));    
        console.log(obj.key);           
    });

    await Promise.all(toWait);
    return toWait;
}

export async function obj_from_snap(co: DataSnapshot) : Promise<(CustomObject | null)>{

        var newCO: CustomObject = {
            val1 : co.val().val1,
            val2 : co.val().val2,
            Data : await GetData(co.key)
        };
        console.log(`Data: ${newCO.Data}`)
        return newCO;
}

export async function getData(key: String) Promise<(String | null)>{
...
}

However, this setup results in an array with empty objects ([{}]). The forEach loop only runs once even though the JSON snapshot contains multiple valid child nodes. Similarly, logging of newCO.Data within the helper function doesn't seem to trigger repeatedly as expected.

I am puzzled as to why this process isn't looping as intended. Additionally, if I were to return the toWait[] array, would it include all the CustomObjects generated by the helper function? If not, what alternative method can provide me with an array of distinct CustomObjects from individual function calls?

Any suggestions or insights? Your assistance is greatly appreciated.

UPDATE

In an attempt to troubleshoot, I simply added a key printing loop within forEach:

    await snap.forEach(async obj => {  
        console.log(obj.key);           
    });
    return null;

Despite having multiple child nodes, only the first key gets printed before the function exits prematurely, returning null. This behavior persists regardless of the number of child nodes present. It seems like the issue lies elsewhere, unrelated to Promise.all(). Any thoughts on this puzzling outcome?

Answer №1

Success! Managed to solve both of my questions. Sharing here for future reference...

async function extractData(snap: any): Promise<(any[] | null)>{
    var data: any[] = [];          // Collection of objects
    const promisesToWaitFor: any[] = [];       // List of promises
    console.log(JSON.stringify(snap));   // Output the input data for debugging

    await snap.forEach(function(item) {     // CHANGED FROM async (item) to function (item)
        promisesToWaitFor.push(processDataFromSnap((item)).then((result) => data.push(result)));    // Appended a chained promise to the initial one, enumerating the result into the final collection
    });
    await Promise.all(promisesToWaitFor);   // Wait until all promises are resolved
    return data;                // Return the processed data
}

The functionality is meeting expectations.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Maintain the specific type based on the provided data, rather than the default value, when a related generic is defined

When it comes to unit tests, I prefer a more flexible approach with dynamic generic types that eliminate the need for type casting. I want T to be open-ended, but if I specify a type, I expect to receive an exact match. For R, I need it to precisely matc ...

The 'subscribe' property is not available on the type '() => Observable<any>'

File for providing service: import { Observable } from 'rxjs/Rx'; import { Http, Response} from '@angular/http'; import { Injectable } from '@angular/core'; import 'rxjs/add/operator/Map'; @Injectable() export clas ...

Issue with RxDB: Collection not found upon reload

Exploring the integration of RxDB in my Angular project. I wanted to start with a simple example: export const LANG = { version: 0, title: "Language Key", type: "object", properties: { key: { type: "string", primary: true } }, requ ...

Understanding the correct way to map two arrays with boolean values is essential for effective data

My situation involves two lists: accounts and accountsWithSelectedField. I initially mapped accountsWithSelectedField like this: this.accountsWithSelectedField = this.accounts.map(s => ({...s, selected: false})); Subsequently, upon receiving a list of ...

Unpacking objects in Typescript

I am facing an issue with the following code. I'm not sure what is causing the error or how to fix it. The specific error message is: Type 'CookieSessionObject | null | undefined' is not assignable to type '{ token: string; refreshToken ...

Trouble occurs in the HTML code when trying to access a property from an inherited interface in Angular

Currently, I am working with Angular 17 and have encountered a specific query: In my project, there is an IDetails interface containing certain properties: export interface IDetails { summary: Summary; description: string; } Additionally, there is an ...

Issue with Ionic Capacitor React & Typescript build process for Firebase Functions

Recently, I've been working on a cutting-edge Ionic Capacitor React application that utilizes Typescript with a Firebase backend. While everything has been running smoothly so far, I encountered some challenges when trying to build Firebase Functions. ...

Performing synchronized execution in a node.js application by utilizing the 'readline' package

Struggling with the asynchronous nature of node.js, despite hours spent on callbacks and researching. I have a program that reads lines from a file using the readline module in node, passing data to async functions within the program. The goal is to proces ...

When trying to retrieve a value from a custom render function in React with TypeScript, an error occurs indicating that the value is not assignable to type 'ReactNode'

Recently, I attempted to develop a versatile swiper component using Next.js 13 (App Router) v13.4.12 along with TypeScript. However, I encountered an issue when trying to access data from the component props, which involves a custom function for rendering ...

What steps can I take to ensure that AstroJS components do not conceal SVG elements when the SVG is incorporated into another file with client:load?

Currently, I am developing a weather application using Astro.js in conjunction with React. One of the features includes an SVG component that serves as the project logo and is implemented in the initial page loader. Upon the page loading, the SVG functions ...

Ways to induce scrolling in an overflow-y container

Is there a way to create an offset scroll within a div that contains a list generated by ngFor? I attempted the following on the div with overflow-y: @ViewChild('list') listRef: ElementRef; Then, upon clicking, I tried implementing this with s ...

What seems to be the issue with the useState hook in my React application - is it not functioning as

Currently, I am engrossed in a project where I am crafting a Select component using a newfound design pattern. The execution looks flawless, but there seems to be an issue as the useState function doesn't seem to be functioning properly. As a newcomer ...

`A bug in my Angular 4 application causes a TypeError when hosted on IIS`

After hosting an Angular 4 app on IIS, it seems there is an issue when accessing the app from machines other than the ones used for development. An error message " 'Uncaught TypeError: undefined is not a function' common.es5.js:3084" appears on t ...

Arranging Worth Based on Offspring

Is there a way to arrange values based on their child value in descending order? Here is the data I have: { "229016449593769984": { "coins": 196 }, "286591003794604034": { "coins": 310 }, "534534453533050240": { "coins": 0 } "423424434234234423": ...

Failed to set the reference: The first argument includes an undefined property. This error occurred within the context of

My journey with Firebase began just 4 days ago, although I've been a bit inconsistent. My goal was to create a user in the database, and while the user was successfully created, I encountered an issue when trying to return to the profile picture page. ...

Prevent Ionic 2 hardware back button from triggering default action

Is there a way to prevent the default navigation when tapping the hardware back button? I attempted using registerBackButtonAction, but it ends up overriding the behavior of the back button on every page, which is not desired. I also tried this method: d ...

Navigating with Gatsby Link and leveraging TypeScript

I am currently utilizing Gatsby Link with TypeScript and I am looking to pass parameters to a linked component from the source component. The documentation provided by Gatsby states the following: Sometimes you’ll want to pass data from the source pag ...

Exploring Ngu-Carousel in Angular 7: Importing JSON data for a dynamic display

After attempting to import data from JSON and display it using ngu-carousel, I encountered an error. The error shows "length of undefined" Subsequently, when I try to click on the previous/next button, another error appears. This error states "innerHTML ...

Tips and tricks for sending data to an angular material 2 dialog

I am utilizing the dialog box feature of Angular Material2. My goal is to send data to the component that opens within the dialog. This is how I trigger the dialog box when a button is clicked: let dialogRef = this.dialog.open(DialogComponent, { ...

Angular service encountering duplicated arrays when retrieving data from Firebase using HTTP.get

While working on my Angular web application, I encountered a strange issue with duplicate arrays in the response from an HTTP get call to a Firebase realtime database. The Firebase setup includes a realtime database configured like this: Firebase data I ...