2

I have a requirement to write an @Effect() which gets an array as input and dispatches api calls to a REST service - each element should produce a call. I then need to dispatch an action to handle the response. A lot of sites recommend using forkJoin but it seems that it waits for all requests to be finished which is not what i reqiure.

I've tried this (without the effect, just a basic example):

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arrObservable$ = from(arr);
 arrObservable$
 .pipe(mergeMap(x => this.http.get('https://jsonplaceholder.typicode.com/posts')))
 .subscribe(x => console.log(x));

But i'm not totally sure the requests are in fact dispatching in parallel.

Thanks in advance.

1 Answer 1

2

Using forkJoin will trigger parallel XHR, but you will only get a response when the last call has finished. Additionally you have to know that, when one single call fails, you complete stream will fail und you won't get any response, even though 9 out of 10 XHR were successfully.

I would suggest the following: Inside your effect you are dispatching multiple actions (for each rest call one). Then you have one additional effect for each rest call, so that you can handle it asynchronously.

@Effect({ dispatch: false })
fetchData = this.actions
  .ofType(FETCH_DATA)
  .pipe(
    map((action: FetchDataAction) => action.payload ),
    map(payload => {
      // repeat as often you need to
      this.store.dispatch(new FetchDataXYAction(payload));
    })
 );


 @Effect()
 fetchDataXY = this.actions
   .ofType(FETCH_DATA_XY)
   .pipe(
     map((action: FetchDataXYAction) => action.payload),
     switchMap(payload => this.service.loadXY(payload).pipe(
       map(res => new FetchDataxySuccessAction(res))
     ))
   );
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for your reply, are there any advantages in your solution as opposed to using mergeMap?
Switch map will abort a pending call / stream if there is one. So if you have multiple requests in a short interval you will only get the response of the last one.
Sure whatever you want or need :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.