Asynchronous problem when using Firebase calls within an Angular ForEach loop

Here's the code snippet I'm working with:

getTotalBookListCost(bookList:string[]):number
  {
    let cost=0;
    bookList.forEach(el=>{
      this.store.doc("Books/"+el).get().subscribe(data=>{
        let temp=<Book>data.data();
        cost+=temp.cost;
      },error=>this.toastr.error(error.message));
    });
    return cost;
  }

The issue is that the value returned is always 0, most likely because the return statement is being executed before the forEach loop completes the Firebase calls. How can we make sure the function returns only after the loop has finished executing?

Answer №1

Absolutely, the function will provide the data prior to Firebase returning it. One potential solution is to utilize the combineLatest operator in the following manner:

getTotalBookListCost(bookList:string[]):Observable<number>
{
  let cost=0;
  return 
  combineLatest(bookList.map(el=>this.store.doc("Books/"+el).get())
  .pipe(
      map(result=> {
        const bookCosts = result.map(data => data.data().cost);
        return bookCosts.reduce(function(a, b) { return a + b; }, 0);
      })
  );
}

It's important to note that your function will now output an Observable instead of just a number.

Edit: as Andrei pointed out correctly, the function previously returned a Subscription instead of an Observable. I have corrected this error, so please remember to subscribe to the Observable.

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

Looking to execute multiple programs simultaneously within the prestart script in the package.json file, and bypass any exit error codes

I need to run yarn tsc and yarn lint during every yarn start to identify any code errors. This is how my scripts property is set up: "scripts": { "start": "expo start", "android": "expo start --android" ...

Convert a nested JSON array into TypeScript class objects

Within the database exist two distinct entities: 'person' and 'name'. These entities share a many-to-many relationship with the properties 'from' and 'to'. Person PersonName Name -- ...

Steps for creating a border around a container Div:1. Set the width and

Seeking assistance in bordering a div with 4 fa-icons inside. The parent div is named Container, and as a result, the border is creating excessive padding on the left and right sides horizontally. Attempted nesting bootstrap grids without success. Can anyo ...

If I include the Next.js Image component within a React hook, it may trigger the error message "Attempting to update state on an unmounted component in React."

My UI layout needs to change when the window width changes. However, when I add an Image (Nextjs component) in my hook, I encounter an error message. I am not sure why adding Image (Nextjs component) is causing this problem. The error message is display ...

What is the solution for the warning "Solid's reactivity is broken when destructuring component props"?

Just starting out with SolidJS and encountering an issue with my UI setup import { render } from "solid-js/web"; import { createSignal, Show } from "solid-js"; import { createStore } from 'solid-js/store'; function Form() { ...

Issue encountered during the creation process of a new component within Angular 4

While attempting to create a new component named signup-form using the command: ng generate component signup-form / ng g component signup-form An error is being thrown that reads: Unexpected token / in JSON at position 1154 The source of this error i ...

Step-by-step guide on importing CSS into TypeScript

I have a global CSS file where I've defined all the colors. I attempted to import that value into TypeScript but it didn't work. This is my latest attempt: get sideWindowStyle(): any { switch (this.windowStyle) { case 'classicStyl ...

Adjust the appearance of matSelect when the selection menu is activated

What is the best way to adjust mat-select properties when its options are open? <mat-select class="selector"> <mat-option><mat-option> </mat-select> .selector:focus { color: green; } I attempted using focus, but ...

The expanded interfaces of Typescript's indexable types (TS2322)

Currently, I am in the process of learning typescript by reimagining a flowtype prototype that I previously worked on. However, I have hit a roadblock with a particular issue. error TS2322: Type '(state: State, action: NumberAppendAction) => State ...

Having trouble parsing the ICU expression. Utilizing angular for internationalization

I need to convert an array of left-menu items into another language, and I am encountering an error in my code. Here is the snippet: left-menu.component.html <ng-container *ngFor="let m of menuItems; let last = last"> <a mat-list-it ...

Issue with Syncfusion Grid: Unable to Display Column Data as Hyperlinks

I'm currently working on a Webapp that utilizes the Syncfusion grid to display tabular data. One of my requirements is to showcase a column's data as a clickable link and trigger a function upon user interaction. After consulting the tutorial av ...

Inadequate handling of the react-router replace function causing issues

I am currently using an onEnter hook that calls the following function: function (nextState, replace) { var unsubscribe = firebase.auth().onAuthStateChanged(function (user) { if (!user) { console.log('attempting to access a se ...

What steps can be taken to properly set up routing in Angular 4 in a way that organizes feature-modules routes as children in the

Organizational layout of projects: /app app.module.ts app.routing.ts : : /dashboardModule /manage-productModule manage-product.module.ts manage-product.routing.ts Within 'app.routing.ts' [ { path : '&a ...

What specifications need to be set up for server and client configurations when using a MEAN Stack application?

When preparing to launch a mid-level enterprise application for the MEAN Stack, what specific configurations are required? How should these configurations be implemented with Angular 2/4/5 and NodeJS? ...

Guide to transforming an embed/nested FormGroup into FormData

Presenting my Form Group: this.storeGroup = this.fb.group({ _user: [''], name: ['', Validators.compose([Validators.required, Validators.maxLength(60)])], url_name: [''], desc: ['', Validators.compose([Valida ...

What is the best way to format text for a copy to clipboard function while using Jasmine?

I've developed a directive for copying content to the clipboard. Here is the code: import { Directive, Input, Output, EventEmitter, HostListener } from '@angular/core'; @Directive({ selector: '[copyClipboard ...

Adapting imports in Typescript for seamless npm distribution

Currently, I'm facing an issue with module resolution while compiling my NPM package written in Typescript for publishing. In my project, I've been using non-relative imports to avoid the hassle of excessive ../../../. However, according to TypeS ...

Angular 4 CanActivateChild fails to function

I'm attempting to limit access to my route system by using the CanActivateChild feature. However, I've encountered an issue where the RouteGuard only works with the CanActivate function and not CanActivateChild. Here's a snippet of my routin ...

Exploring an array in Angular 2 using TypeScript

Just starting out with typescript and angular2 and working through some issues. I have a form that needs to display results from an array of changing items, so I don't know the exact index of each result. Here is my scenario: In my form.html file: ...

Sorry, but you can only use one 'in' filter in your query

this.ref.collection("users", ref => ref.where("uid1","in", [reciverId, senderId]) .where("uid2","in", [reciverId, senderId])) throws an error stating: "Invalid query. Multiple 'in' filters cannot be used." ...