Michael Harper
Michael Harper

Reputation: 1531

Angular rxjs sets of sequential http calls

I'm writing a function using concatMap to make HTTP calls sequentially, e.g. add a person, use some info returned to add a contact then add some accounts.

The function receives a list (portfolios in my case) and for each portfolio I need to create calls to addAccount and addInvestorAccount.

So for example two portfolios would require two sets of calls to these endpoints (addInvestorAccount is dependent on the result of addAccount)

I'm unsure how to create these dynamic sets of HTTP calls and attach them to the current stream. I've looked at forkJoin but this appears to be for parallel calls that are independent.

Hope this makes some sense, here's some demo 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))
}

As you can see above I'm using Portfolio[0], obviously I need to iterate the portfolios for addAccountRequest and addInvestorAccountRequest

Thanks!

Upvotes: 2

Views: 3348

Answers (1)

LLai
LLai

Reputation: 13396

I think you are on the right track with forkJoin. You can forkJoin (parallel) calls that are in series. I would make a separate method that chains your 2 dependent calls.

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 will be used to make x amount of chained portfolio requests. Now within your original method, make an array of all the portfolios you need

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) => {
            // build out all portfolio requests
            let portfolioObservables = portfolios.map((portfolio: Portfolio) => {
                return this.makePortfolio(response, portfolio);
            }

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

So what is effectively happening is addPersonRequests -> emailContactRequest -> in parallel (addAccountRequest -> addInvestorAccount Request)

Obviously alot of requests are being made. If possible, I would recommend updating your HTTP requests to accept multiple portfolios/accounts at once. But if that is not an option, this would be a way to accomplish the chained sequence.

Upvotes: 4

Related Questions