What is the best way to merge multiple nested angular flattening operators together?

I am facing a challenge in utilizing the outcomes of Observables from various functions. Some of these functions must be executed sequentially, while others can run independently. Additionally, I need to pass the result of the initial function to some nested ones.

Despite exploring numerous examples, I am struggling to comprehend this particular combination. The syntax seems perplexing to me.

Consider the scenario where each of the following functions returns an Observable:

saveContactDetails() : Observable<ContactDetails> {
    // Returns a single observable with ContactDetails.
}

savePhones(contactId: string) : Observable<Phone[]> {
    // Returns a single observable with an array of Phones.
}

saveEmails(contactId: string) : Observable<Email[]> {
    // Returns a single observable with an array of Emails.
}

saveAll(): Observable<Contact> {
    // TODO: Having trouble figuring out the logic/syntax here.
}

Steps:

  1. Invoke saveContactDetails(). Proceed only after its completion.
  2. Upon receiving the result of saveContactDetails(), invoke savePhones() and saveEmails(). These two functions (and potentially more) can execute concurrently without any specific order.
  3. Once all "child" Observables have finished processing, merge the results of all (parents and children) into a single Observable to be returned by saveAll().

I speculate that I need to utilize concatMap and mergeMap (or maybe forkJoin). Nonetheless, I am unable to grasp the syntax despite consulting online documentation and examples.

Answer №1

This is what the code looks like when implemented.

First, you switchMap into a forkJoin in order to combine results from multiple sources that require input from the initial source. Then, an inner map function is used to merge the results from all three.

saveAll(): Observable<Contact> {
    return this.saveContactDetails().pipe(
      switchMap(contactDetails => forkJoin([
          this.savePhones(contactDetails.id), // wherever the id comes from
          this.saveEmails(contactDetails.id)
        ]).pipe(
          map(([phones, emails]) => 
            Object.assign(contactDetails, {phones, emails})) // any transformation needed
        )
      )
    );
  }

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

Using ServiceWorker with React and Typescript

If you are working on a javascript-based React project, adding a Service Worker is simply a matter of updating serviceWorker.unregister() to serviceWorker.register() in index.jsx. Here is an example project structure: - src |- index.jsx |- serviceWo ...

Active Class in Angular Dynamic Carousel

I recently set up a dynamic carousel that pulls images directly from a node backend. While everything seems to be in working order, I've run into an issue where all the images are being displayed at once instead of sliding through one at a time. This ...

What is the significance of having both nulls in vue's ref<HTMLButtonElement | null>(null)?

Can you explain the significance of these null values in a vue ref? const submitButton = ref<HTMLButtonElement | null>(null); ...

In React + TypeScript, learn how to effectively pass down a function from a container component to a

I am currently working on developing a tabs application using React and Typescript. The main component, Tabs, manages the state and passes it down to the Content component. Additionally, I have implemented a function called 'handleName' which is ...

The Highcharts Angular library is struggling to access the 'series' property due to it being undefined

Encountered an error message that has puzzled me. I am eager to explore highstock.js and its associated files, but I'm uncertain about the best approach. Despite the chart displaying correctly, this error consistently arises. ...

Ways to conditionally display a component in Next.js without the issue of caching CSS styles

I'm a newcomer to Next.js and I'm still trying to wrap my head around how the caching works. Let's take a look at this simplified example: An index page that displays either Test1 or Test2 components, based on whether the current minute is ...

Prevent the Vue page from loading until the data has been fetched successfully

I'm in the process of finding a way to prevent my page from loading until my fetch task is completed. I'm facing some issues that need to be addressed: I have to re-fetch the data each time because I can't reuse the same data. (Changing vie ...

The module 'pouchdb' appears to be missing, functioning correctly on Mac but encountering issues on Windows

I have taken over a project built with Ionic that was originally developed on a Mac by my colleague. I am now trying to run the project on my clean Windows 10 PC with Ionic, Cordova, and Python installed. However, I am encountering an error that my colleag ...

Transform webservice data into TypeScript object format, ensuring mapping of objects from capital letters to camel case

Something peculiar caught my attention in my Angular2 TypeScript project. When objects are fetched from a web service, they have the type "Level" and the properties are in Pascal case. However, during runtime, I noticed that the properties of these Levels ...

The Angular4 HTTP POST method fails to send data to the web API

Whenever I make a http post request, it keeps returning an error message saying "data does not pass correctly". I have tried passing the data through the body and also attempted using json.stringify(). Additionally, I experimented with setting the content ...

How can an array be generated functionally using properties from an array of objects?

Here's the current implementation that is functioning as expected: let newList: any[] = []; for (let stuff of this.Stuff) { newList = newList.concat(stuff.food); } The "Stuff" array consists of objects where each ...

Tips for modifying only one property after receiving an object from an HTTP GET request

Within my Angular application, I have defined an object structure like this: export class Article { id: number; author: number; title: string; content: string; date: Moment; readingTime: number; draft: boolean; constructor(obj: Partial< ...

Building stateless functional components in React using Typescript version 0.14

Demonstration: import * as React from 'react' declare function obtainMarineLife(x: any): any; declare var Tank: any; var OceanicHabitat = ({category}) => ( <Tank> {obtainMarineLife(category)} </Tank> ); let y = <Ocea ...

Merge the values of an object's key with commas

I'm dealing with an array of objects that looks like this: let modifiers = [ {name: "House Fries", price: "2.00"}, {name: "Baked Potato", price: "2.50"}, {name: "Grits", price: "1.50"}, {name: "Nothing on Side", price: "0.00"} ] My goal is to con ...

What is the best way to set up my page to detect the "enter" key input when the form is not created with the <form> tag?

Within the HTML code, data is received and stored in variables within my TypeScript file. At the end of the HTML, there is a button that was created separately from any user input containers. This button triggers a function that processes the information i ...

Steps for transferring an uploaded .CSV file to a Web service

I'm exploring the process of sending a file uploaded from the UI (angular) to a .NET web service in order for it to parse a CSV file and create a list of objects. My current understanding of the logic flow is: File upload ---> Web Service (parse ...

Using NgRx to observe state changes in a service instead of relying on an Effect

Is it possible for a service to monitor state changes and make HTTP calls based on the state value without being triggered by an effect (NgRx)? In other words, can a service react to a portion of the store and eliminate the need for an effect to be involve ...

The return value depends on the type of function argument passed

I am currently developing a type-safe JSON:API specification parser for handling API responses that can either contain a single object or an array of objects (). For example, when making a request like GET /article: { data: { type: 'article&ap ...

Angular dependency-wheel chart powered by Highcharts

Recently, I've been working on incorporating the dependency-wheel chart from the Highcharts-angular Library into my project. The library can be found at this link. Despite creating a simple stackBlitz example with minimal configuration, I keep encoun ...

The display of the selected input is not appearing when the map function is utilized

I am attempting to use Material UI Select, but it is not functioning as expected. When I use the map function, the default value is not displayed as I would like it to be. However, it does work properly when using the traditional method. *** The Method th ...