Upgrading the subscription structure to fetch multiple details from a single initial request containing IDs

In my project, I am making multiple calls to two different backend services. The first call is to retrieve the IDs of "big" items, and then subsequent calls are made to get the details of each "big" item using its ID.

I have explored options like concatMap(), switchMap(), mergeMap() from various sources such as a helpful post on Stack Overflow: Rxjs One Observable Feeding into Another. However, I am struggling to figure out how to loop through an unknown number of calls to the second collection.

The current approach I am using works fine, but I want to move away from nested subscriptions.

Should I consider using Promises instead of RxJS for this particular task?

loadWigitsDetailed() {
  this.wigitGetterService
    .fetchWigitIds({
      category: 'big'
    })
    .subscribe(response => {
      // say, 5 items returned.
      for (const oneWig of response.items) {
        this.detailedWigitInfoService.fetchWigitInfo({ id: oneWig.id })
          .subscribe(responseDetail => {
            wigitTable.addRow(responseDetail);
          });
      }
    });
}

Answer №1

If you're looking to achieve this task, you have the option of utilizing Promises or exploring the potential of RxJS. Below is a possible way to tackle it:

loadWigitsDetailed() {
  this.wigitGetterService.fetchWigitIds({ category: 'big' })
    .pipe(
      // Expand the items array into a sequence of items
      mergeMap(response => response.items),
      // Retrieve detailed information for each item
      mergeMap(eachWig => this.detailedWigitInfoService.fetchWigitInfo({ id: eachWig.id }))
    )
    .subscribe(responseDetail => {
      wigitTable.addRow(responseDetail);
    });
}

If the order is not crucial, utilize mergeMap. However, if maintaining a specific order is essential, consider substituting mergeMap with concatMap.

Answer №2

My strategy involves leveraging the power of switchMap and forkJoin. Firstly, we utilize an observable to retrieve all the ID fields, followed by applying switchMap to transition from the outer observable to the inner one. The array is then transformed into an array of observables containing the respective details. Subsequently, forkJoin is used to concurrently call the APIs and ultimately return the array with the complete information, which can be assigned to any variable for usage.

fetchDetailedWidgets() {
  this.widgetService
    .retrieveWidgetIds({
      type: 'large'
    }).pipe(
      switchMap((response: any) => {
        const apiArray$ = response.items.map((singleWidget: any) => this.infoService.getWidgetInfo({ id: singleWidget.id }))
        return forkJoin(apiArray$);
      })
    )
    .subscribe((detailedWidgetsTable: any) => {
      this.detailedWidgetsTable = detailedWidgetsTable;
    });
}

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

Adjusting the interface of a third-party TypeScript library

I am currently working on modifying a third-party interface. I'm curious about why this particular code is successful: import { LoadableComponentMethods as OldLoadableComponentMethods } from '@loadable/component'; declare module "load ...

Utilize CountUp.js to generate a dynamic timer for tracking days and hours

I am looking to create a unique counter similar to the one featured on this website https://inorganik.github.io/countUp.js/ that counts up to a specific number representing hours. My goal is to display it in a format such as 3d13h, indicating days and hour ...

Display a pair of distinct items side by side on a webpage

When needing to display information in the format below: Reason : reason number 1 reason number 2 reason number 3 Code : code number Remarks : remark In this scenario, Reason, Code, and Remarks serve as headings enclosed in <s ...

Turn off Typescript compilation in Visual Studio for a webpage

My Angular website (not a computer science project) is integrated into a solution, causing Visual Studio 2019 to generate multiple TypeScript compilation errors while working on other projects within the same solution. You can see examples of these errors ...

What could be causing my component to not refresh when used as a child?

I have been experimenting with some code to track rerenders. The initial approach failed when passing <MyComponent> as a child component. it("should return the same object after parent component rerenders", async () => { jest.useF ...

"Error: The specified object does not have the capability to support the property or method 'includes'." -[object Error]

Recently, I developed a method that utilizes both indexOf() and includes(). However, I encountered an error message stating "Object doesn't support property or method 'includes'". I have attempted to run the method on both Internet Explorer ...

What are some tips for integrating AppInsights with Angular?

Trying to integrate AppInsights with Angular has been a bit challenging for me: import { AppInsights } from 'applicationinsights-js'; .... if (!AppInsights.config) { var config: Microsoft.ApplicationInsights.IConfig = { instrumenta ...

An error message stating 'Cannot read the name property of undefined' is being displayed, despite it being expected to be defined

interface InputField { readonly label : string; readonly data : string; readonly displayInline ?: boolean; } class FormField implements InputField { readonly label : string; readonly data : string; readonly displayInline ?: boolean; constru ...

How to detect changes in Angular2 forms

Exploring Angular2 4.0, I've created a FormGroup structured as follows: this.form = this._fb.group({ a: ['', [Validators.required]], b: ['', [Validators.required]], c: ['', [Validators.required]], ...

Tips for resetting a form after submission

Hey there, I'm currently working with Angular 7 and facing an issue with form submission. After submitting the form successfully, I want to reset it without triggering the required validation for input fields. Here's a snippet of my TypeScript co ...

Is it not possible to type a Specific Object Type as a Record?

I am looking to create a generic Table Row interface that will only allow objects with primitive attribute values. However, when I try to assign a specific type of object to the row, it fails. Why is this happening and how can I make it work? My goal is to ...

How does a brand new installation of VSCode believe it comes pre-equipped with TypeScript capabilities?

Operating on Windows 10 Enterprise, After investing several hours and experimenting on various VMs, Interesting Observation #1 Upon opening a .ts file in vscode, it appears to be recognized as TypeScript 2.3.4 as per the screenshot provided below: http ...

Ways to update property values of an array object in JavaScript

I am trying to match values from one array object with another array and update the status if there is a match. Here's the desired output for arrObj: [ { name: "Test1", status: true }, { name: "Test2", status: false }, { name: "Test3", s ...

Sticky Angular header that keeps content visible while scrolling - no disappearing into the header

I came across a discussion about sticky headers and implemented the following Angular layout: <div fxLayout="column"> <div class="sticky"> <app-header></app-header> <app-navbar></app- ...

What is the appropriate event type to pass to the onKeyPressed function in a React application utilizing MaterialUI and written with Typescript?

I am currently working on a React application using Typescript and MaterialUI, where I have implemented a TextField component. My goal is to capture the value of the input HTML element when the user presses the enter key. To achieve this, I have created ...

Attempting to modify read-only properties is prohibited in strict mode within the context of [background: url({{XXX}}) no-repeat center center

I encountered an issue in Edge, but everything works fine in Chrome. I can't figure out what's causing the problem... <div class="container-fluid project_img" style="background: url({{_project.images.web}}) no-repeat center center;"> ...

The issue with session storage persisting even after closing the iframe

Encountering a persistent issue where the sessionStorage remains populated even after closing an iframe and opening another one with the same destination. I assumed that the sessionStorage would be reset and start afresh each time. The iframe is contained ...

What are the best ways to format text conditionally depending on a form's status?

Is there a way to change the text color in an HTML form to be red when the form is invalid and green when it is valid using Angular 8? (HTML) <p class="status"> Form Status: {{ Form.status }} </p> (TS) Form = this.fb.group({ ...

What sets apart a class from a service in NativeScript?

I am embarking on the journey of learning Nativescript + Angular2, and while reading through the tutorial, I came across this interesting snippet: We’ll build this functionality as an Angular service, which is Angular’s mechanism for reusable classes ...

Compelled to utilize unfamiliar types in TypeScript generics

When working with a Typescript React form builder, I encountered a situation where each component had different types for the value and onChange properties. To tackle this issue, I decided to utilize generics so that I could define the expected types for e ...