Consecutive HTTP requests in Angular using rxjs

Currently working on a function that utilizes concatMap to perform sequential HTTP calls, such as adding a person, using the returned information to add a contact, and then adding some accounts.

This function takes in a list (in my case, portfolios) and for each portfolio, I must make calls to addAccount and addInvestorAccount.

For example, if there are two portfolios, it would require two separate sets of calls to these endpoints (addInvestorAccount depends on the result of addAccount).

I'm trying to figure out how to dynamically create these sets of HTTP calls and append them to the current stream. I've looked into forkJoin, but it seems to be more suitable for parallel independent calls.

I hope this explanation is clear. Here is a snippet of the code:

AddPerson(person: Person, portfolios: Portfolio[]) {
const addPerson = new AddPersonRequest();
// additional request props
return this.hostSvc.put(addPersonRequest)
    .concatMap((response: Person) => {
        const emailContactRequest = new CreateContactRequest();
        emailContactRequest.PersonId = response.Id;
        // additional request props
        return this.hostSvc.put(emailContactRequest)
    })
    .concatMap((response: AccountName) => {
        const addAccountRequest = new AddAccountRequest();
        addAccountRequest.Data = new Account();
        addAccountRequest.Data.AccountId = response.Id 
        addAccountRequest.Data.PortfolioId =  portfolios[0].Id
        // additional request props

        return this.hostSvc.put(addAccountRequest);
    })
    .concatMap((response: Account) => {

        const addInvestorAccountRequest = new AddInvestorAccountRequest();
        addInvestorAccountRequest.Data = new InvestorAccount();
        addInvestorAccountRequest.Data.AccountType = response.AccountType
        // additional request props
        return this.hostSvc.put(addInvestorAccountRequest);
    }, (error) => console.log(error))
}

In the code provided above, you'll notice I'm using Portfolio[0], but I actually need to iterate through all portfolios for addAccountRequest and addInvestorAccountRequest.

Thank you!

Answer №1

It seems like you're heading in the right direction by using forkJoin to handle parallel calls that need to be executed in series. One suggestion I have is to create a separate method that handles chaining your dependent calls together.

makePortfolio(accountName: AccountName, portfolio: Portfolio){
    const addAccountRequest = new AddAccountRequest();
    addAccountRequest.Data = new Account();
    addAccountRequest.Data.AccountId = accountName.Id 
    addAccountRequest.Data.PortfolioId =  portfolio.Id;

    return this.hostSvc.put(addAccountRequest)
        .concatMap((response: Account) => {
            const addInvestorAccountRequest = new AddInvestorAccountRequest();
            addInvestorAccountRequest.Data = new InvestorAccount();
            addInvestorAccountRequest.Data.AccountType = response.AccountType
            // additional request props
            return this.hostSvc.put(addInvestorAccountRequest);
        });
}

This method can then be used to handle a series of chained portfolio requests. In your original method, create an array of all the portfolios that need to be processed

AddPerson(person: Person, portfolios: Portfolio[]) {
    const addPerson = new AddPersonRequest();
    // additional request props
    return this.hostSvc.put(addPersonRequest)
        .concatMap((response: Person) => {
            const emailContactRequest = new CreateContactRequest();
            emailContactRequest.PersonId = response.Id;
            // additional request props
            return this.hostSvc.put(emailContactRequest)
        })
        .concatMap((response: AccountName) => {
            // construct individual portfolio requests
            let portfolioObservables = portfolios.map((portfolio: Portfolio) => {
                return this.makePortfolio(response, portfolio);
            }

            // execute portfolio requests in parallel
            return Observable.forkJoin(...portfolioObservables);
        });
}

So essentially, the flow would be addPersonRequests -> emailContactRequest ->

in parallel (addAccountRequest -> addInvestorAccount Request)

A lot of requests are being made in this process. If feasible, consider updating your HTTP requests to allow for multiple portfolios/accounts to be submitted at once. However, if that's not an option, this approach should help achieve the desired sequential execution of requests.

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

Merge type guard declarations

After studying the method outlined in this post, I successfully created an Or function that accepts a series of type guards and outputs a type guard for the union type. For example: x is A + x is B => x is A | B. However, I encountered difficulties usin ...

Angular checkbox filtering for tables

I have a table populated with data that I want to filter using checkboxes. Below is the HTML code for this component: <div><mat-checkbox [(ngModel)]="pending">Pending</mat-checkbox></div> <div><mat-checkbox [(ngModel ...

Diverse Selection of Font Awesome Icons

In my React project with TypeScript, I have a header component that accepts an Icon name as prop and then renders it. I am trying to figure out the best way to ensure that the icon prop type matches one of the existing FontAwesome Icons. import { FontAwe ...

Creating mock helper classes in Jasmine unit tests

One of the challenges I'm facing is writing unit tests for an Angular component that relies on a helper class. The requirement is to exclude the helper class and its functions from this particular test by mocking them instead. Here's how the comp ...

Using the useEffect hook with Redux-Toolkit dispatch causes an endless cycle of execution

Issue I am encountering an infinite loop problem when using useMutation from react-query to make post requests, retrieve user information from JSON, and then store it in my redux store using useEffect based on the status provided by the useMutation hook. ...

Dynamically loading Angular modules based on API response is a powerful way to enhance

Can modules be lazily loaded in Angular without a static declaration in the RoutingModule? Right now, each module is declared in the RoutingModule. { path: 'path-one', loadChildren: () => import('./components/PathOne').then(m =&g ...

What is the relationship between directives, templates, and ViewContainers in Angular?

I have implemented a basic functionality in my component where numbers are injected after a delay using a custom directive called *appDelay It is known that the Angular syntax hints with * will de-sugar into something like this: <ng-template ...> .. ...

Creating an Angular project with two different base-href configurations

Angular CLI: 7.2.3 Node: 10.14.1 OS: darwin x64 Angular: 7.2.2 Currently, my index.html file includes a base href set to <base href="/" /> and the application runs at http://localhost:port/ I am wondering if there is a way for my app to run both at ...

Tips for maintaining a marker at the bottom of the screen while zooming, similar to Google Maps

Is there a way to customize the zoom behavior in my project? I want to maintain the bottom position while resizing the other three directions, and also include pitch adjustments. https://i.sstatic.net/hQdg8.gif https://i.sstatic.net/m3xef.gif I aim for t ...

Can we verify if strings can serve as valid property names for interfaces?

Let's consider an interface presented below: interface User { id: string; name: string; age: number; } We also have a method defined as follows: function getUserValues(properties:string[]):void { Ajax.fetch("user", properties).then( ...

Rows nested within the Bootstrap grid system

Looking to implement a nested grid within a parent grid in Bootstrap 3.3.7. Check out the HTML below: Parent component <div> <div class="row"> <div class="col-md-3 border">.col-md-3</div> // <div class="col-md-9 ...

Using Angular NgUpgrade to inject an AngularJS service into an Angular service results in an error message stating: Unhandled Promise rejection: Cannot read property 'get' of undefined; Zone:

I have noticed several similar issues on this platform, but none of the solutions seem to work for me. My understanding is that because our Ng2App is bootstrapped first, it does not have a reference to $injector yet. Consequently, when I attempt to use it ...

This error message in AngularJS indicates that the argument 'fn' is not being recognized as a function

I am currently working with angularjs and typescript and I am attempting to create a directive in the following manner: Below is my controller : export const test1 = { template: require('./app.html'), controller($scope, $http) { ...

Developing in TypeScript with styled-components allows for seamless integration between

New to TypeScript and seeking guidance. I currently have a component utilizing styled-components that I want to transition to TypeScript. import React from 'react' import PropTypes from 'prop-types' import styled from 'styled-comp ...

The search functionality in the unit test could not be executed as it is

Encountering an error this.sourceAccounts.find is not a function while running unit test on an array. component.ts: sourceAccounts: Array<IObject>; nameChangedSubscription: Subscription; constructor(private accountService: AccountService) { } ngOn ...

Converted requests from loopback to angular2 resulted in an error message, as the script's MIME type ('text/html') was determined to be non-executable

Currently, I have set up loopback as the backend API and angular2 as the frontend for my project. Loopback is serving my angular2 frontend without any issues. However, whenever I refresh a page, loopback seems to struggle with handling the URL because tha ...

Unable to execute the "install code command in PATH" command

I am encountering an issue with Visual Studio Code where the "install code command in path" option does not show up when I try to access it using Shift + Ctrl + P. My operating system is Windows 10 and I am running the latest version of Visual Studio Code. ...

For each array element that is pushed, create and return an empty object

I am encountering an issue with an array where the objects are being generated by a push operation within a function. Despite successfully viewing the objects directly in the array, when I attempt to use forEach to count how many times each id uses the ser ...

Unable to retrieve local property when inside a Callback function in Ionic2

I am encountering an issue with my Ionic 2 app that utilizes Angular2. It is a basic problem, but it has been quite frustrating for me. Below is the component in question... import {Component} from "@angular/core"; @Component({ '<ion-content> ...

When evaluating code with eval, properties of undefined cannot be set, but the process works seamlessly without

Currently, I am attempting to utilize the eval() function to dynamically update a variable that must be accessed by path in the format myArray[0][0[1][0].... Strangely enough, when I try this approach, I encounter the following error: Uncaught TypeError: ...