Nested http calls inside @effects

621 views Asked by At

I have and angular2 application running ngrx store with effects for handling the http requests. Working fine for straightforward simple http requests: REQUEST -> SUCCESS/FAIL actions that ends modifying my store status.

What I am trying to do now is to do a first call which will return me an array of persons and for each person that is returned I need to do a http call to get some extra data from them.

What I would like to achieve is to get the persons, fetch the extra data as soon as I get the persons and then trigger the "Success" action with the complete data.

Here is the original effect for a simple persons request. working fine:

@Effect() requestManagers = this.action$
    .ofType(ContributionActions.FETCH_MANAGERS_REQUEST)
    .map(toPayload)
    .switchMap(payload => this.contributionsService.requestManagers()
        .map(res => this.contributionActions.fetchManagersReceive(res.json()))
        .catch(err =>
            this.errorHandler.handleError(err, 'There was an error retrieving your managers', this.contributionActions.fetchManagersFailed())
        )
    );

Here is my try to do an http request for each manager that I receive. Using forkJoin for doing in parallel the "details" call for the n managers that i get from the first call.

  • for the second call I use a toPromise() http call
  • forkJoin to get the results from all the calls triggered

before the return line return this.contributionActions.fetchManagersReceive(managers); i can print the variable "managers" and they are formatted with the original data plus the extra data from the "details" call, so working as intended.

but at dispatching the "recieve" action this.contributionActions.fetchManagersReceive(managers); I get the following error:

Effect "ContributionEffects.requestManagers" dispatched an invalid action

@Effect() requestManagers = this.action$
    .ofType(ContributionActions.FETCH_MANAGERS_REQUEST)
    .map(toPayload)
    .switchMap(payload => this.contributionsService.requestManagers()
        .map(res => {
            const managers = res.json();
            const managersContributionsCallArray = [];

            managers.map(manager => {               
                const data = {
                    reviewId: manager.review_id
                }               
                managersContributionsCallArray.push(this.contributionsService.requestManagerContributionsPromise(data));                    
            });

            Observable.forkJoin(managersContributionsCallArray).subscribe(results => {
                for (var index = 0; index < managers.length; index++) {                     
                    managers[index]['contributions'] = results;                     
                }

                return this.contributionActions.fetchManagersReceive([managers]);

            });
        })
        .catch(err =>
            this.errorHandler.handleError(err, 'There was an error retrieving your managers', this.contributionActions.fetchManagersFailed())
        )
    );

This is how I tried so far to get the expected result, any idea on how to make this work would be appreciated.

I Would also like to know if there is a better approach to get the same result that I am looking for, since I'm pretty sure that there is a more efficient and pretty way to do the same.

Thanks in advance.

0

There are 0 answers