Finding out when the entire subscription loop has ended in an Angular 2+ application can be accomplished through various detection techniques

Currently, I am utilizing Angular 13 with TypeScript. Within my Service class, there is a method that carries out a get request to a REST API:

getProduct(productId): Observable<Product> {
    const productUrl = `http://localhost/api/products/${productId}`;
    return this.httpClient.get<Product>(productUrl);
}

Additionally, I have an array of product IDs:

let productIds: string[] = ['1', '2', '3', '4', ...];

My goal is to invoke the getProduct() method for all product IDs and then perform another action once all the calls have completed. I have tried utilizing a for loop to call getProduct() for each ID, but the asynchronous nature of the code means that the code following the loop executes immediately, rather than waiting for all products to finish processing.

Here is the code snippet for calling getProduct():

async getAllProducts() {
    for(const productId of this.productIds) {
      let product : Product = await this.productService.getProduct(productId).toPromise();
      .
      .
      // perform additional actions
    }
}

There is another method in the same class:

foo() {
    this.getAllProducts();
    // I would like the remaining code here to only run once getAllProducts() has completed its tasks
}

Any assistance is greatly appreciated.

Answer №1

Follow this example code to achieve the desired outcome:

public retrieveAllProducts(): Observable<any> {
  const products$: Array<Observable<any>> =
    (this.productIds || []).map((productId) =>
      this.productService.getProduct(productId)
    ) || [];
  return forkJoin(products$);
}

bar(){
  this.retrieveAllProducts().subscribe((result) => {
    // the following code will only execute after retrieveAllProducts() has finished
    console.log(result);
  });
}

Update: Try using Promises

If you prefer to use promises, you can utilize the code below:

public retrieveAllProducts(): Promise<any> {
  const promises: Array<Promise<any>> = (this.productIds || []).map((productId) =>
    this.productService.getProduct(productId).toPromise()
  ) || []
  return Promise.all(promises);
}

async bar(){
  const products = await this.retrieveAllProducts();
  console.log(products)
}

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

Tips for addressing the ESLint issue stating that the package should be included in dependencies instead of devDependencies

Struggling to properly lint my React+Typescript project with ESLint. In one of my components, I'm utilizing the useParams hook from react-router. import { useParams } from 'react-router'; However, ESLint is throwing an error on that line: E ...

Dealing with Errors - Utilizing Observable.forkJoin with multiple Observable instances in an Angular2 application

One of my Angular applications has two objects, Observable<Object1[]> and Observable<Object2[]>, that call different APIs in the resolver: resolve(): Observable<[Array<Object1>, Array<Object2>]> { const object1 = this.boo ...

Angular 10 library devoid of ivy technology

After successfully building an Angular 10 library and using it via a direct import (file:dist/my-lib), I decided to publish the library to a private npm repository. To accomplish this, I made changes to my tsconfig.lib.json file and disabled ivy: "ang ...

Launching a Node.js application on a Kubernetes cluster

Currently, I have a local Angular 6 application that I run using "npm start." My next goal is to deploy this application in Kubernetes. However, I'm unsure about how to dockerize an Angular 6 based application and run it in Kubernetes. Any assistance ...

Angular Firebase Email Verification sent to an alternate email address

I am facing a challenge with my website that only accepts emails from a specific domain, such as a university domain. Users who want to sign up using Facebook or Google need to verify their university email, but I am struggling to find a way to send the ve ...

Can you point me in the direction of the Monaco editor autocomplete feature?

While developing PromQL language support for monaco-editor, I discovered that the languages definitions can be found in this repository: https://github.com/microsoft/monaco-languages However, I am struggling to locate where the autocompletion definitions ...

The mat-table component in my HTML code is not displaying the dataSource as expected, even though I meticulously copied it from Material Angular

Although I am aware that my question may seem unusual, my issue precisely matches what the title conveys. The problem lies in my mat-table dataSource not displaying any data, even after attempting to log the data with console.log("My Data : ", this.dataSou ...

Angular 5 mobile row aligns vertically, not inline with Bootstrap

Is there a way to make the row inline when the width is less than 579px? I want it to look the same on both mobile and desktop. "styles": [ "../node_modules/font-awesome/scss/font-awesome.scss", "../node_modules/angular-bootstrap-md/scss/bootstra ...

The promise is only guaranteed to resolve correctly upon the refreshing of the page

Exploring an API that retrieves a list of Pokemon and related data, the code snippet below demonstrates how to achieve this. export function SomePage() { const [arr, setArray] = useState([]); useEffect(() => { fetchSomePokemon(); }, []); f ...

transform JSON structure into an array

Is it possible to convert an interface class and JSON file into a list or array in order to work on it? For example, extracting the Racename from each object in the JSON file and storing it in a list/array. Here is the interface structure: interface IRunn ...

What is the method by which the Material-UI Button component determines the properties for the component that is passed to the `component` prop

Could someone please clarify how Material-UI enhances the properties of its Button component by incorporating the properties of a specific component if passed in the component attribute? interface MyLinkProps extends ButtonBaseProps { someRandomProp: str ...

Collaborate on input field values across different Angular components

I'm currently exploring Angular 8 and facing an issue with two forms in separate components that share some input values. These values update whenever the user leaves the input field. The first component contains these input fields: <input matInp ...

Navigational assistance on the keyboard - Improving Accessibility

My situation involves selecting an option from a dropdown menu on X-page, which triggers the opening of Modal-1 while disabling the background. If a selection is made within Modal-1, it leads to Modal-2. I am facing two issues/questions: Upon opening Moda ...

How can I create a customized scrollbar for a div element in an Angular 2.0 CLI project?

I am attempting to create a sleek horizontal scroll bar within one of my div elements, similar to the example shown here: https://i.stack.imgur.com/ziWhi.png My project is based on the angular2 CLI. Progress so far: I came across this package angular2-s ...

Unexpected token { in Fuse-Box when using Typescript

Here's the beginning of my fuse.ts file import { CSSPluginOptions } from 'fuse-box/plugins/stylesheet/CSSplugin'; import { argv } from 'yargs'; import * as path from 'path'; import { CSSPlugin, CSSResourcePlugin, Env ...

Creating an instance of a class using a class decorator, with or without the 'new'

Seeking alternatives to creating class instances without using the new keyword in TypeScript, I came across this excellent solution that works seamlessly in JavaScript. The code found in the repository mentioned https://github.com/digital-flowers/classy- ...

Error message: The database query function is encountering an issue where the property 'relation.referencedTable' is undefined and cannot be accessed

Currently, I am working with two schemas named products.ts and category.ts. The relationship between these files is defined as one-to-many. In the products.ts file: import { pgTable, timestamp, uuid, varchar } from "drizzle-orm/pg-core"; import ...

Optimizing row performance for Angular grids in the Chrome browser

When creating a component that includes a table with numerous rows, everything works well with small amounts of data. However, once the item count reaches 2000 or more, it starts lagging. Scrolling and animations become sluggish. Even after trying to impl ...

Navigate the nested route of a child page starting from the main Root component

I am facing an issue with enabling nesting routes on the BarcodeScannerComponent component. I have attempted the following method, but it does not seem to work. The main challenge lies in accessing the nested route within the root component, which is app.c ...

Unable to connect to localhost nodejs server from Windows browser when using WSL2

My computer runs on Windows 10 and has the Linux (Ubuntu-20.04) subsystem using WSL2. I've successfully initiated a frontend project (vue project) and running npm run serve works as expected with the application running on localhost:8080. However, whe ...