Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

During a forkJoin, how can I dispatch an action for each request as well as when they all complete?

Tags:

rxjs

redux

ngrx

I'm using ngrx in an Angular project. In this example I have an array of requests. I want to dispatch an action after each request but also after all are done.

So far I have something looking like this:

Observable.forkJoin(requests).pipe(
  map(() => new actions.requestsSuccessful()),
  catchError(() => of(new actions.requestsFailed()))
);

where requests is an array of Observables.

The code above works fine, when all requests are done, my requestsSuccessful() action is correctly dispatched.

However, I'm implementing a progressbar, which I want to update after each request has been made, but I also want to keep the dispatch of the action where all requests have been made.

I can't figure out how to dispatch an action after each request while keeping the action when everything is done.

Any ideas?

like image 476
Weblurk Avatar asked Oct 14 '25 14:10

Weblurk


1 Answers

forkJoin emits only when all Observables complete so it's not useful here. Instead, you can use concatAll and concat.

This is model example simulating what you want if I understand you correctly.

const makeRequest = (v) => of(v)
  .pipe(
    delay(1000), // Simulate delay
    map(response => ({ action: 'WHATEVER', response })), // Map response into action
  );

const requests = [makeRequest(1), makeRequest(2), makeRequest(3)];

from(requests)
  .pipe(
    concatAll(), // Execute Observables in order one at the time
    concat(of({ action: 'ALL_DONE' })), // Append this when all source Observables complete
  )
  .subscribe(console.log);

See live demo (open console): https://stackblitz.com/edit/rxjs6-demo-zyhuag?file=index.ts

This demo will print the following output:

{action: "WHATEVER", response: 1}
{action: "WHATEVER", response: 2}
{action: "WHATEVER", response: 3}
{action: "ALL_DONE"}

Btw, in future RxJS versions there will be endWith operator that you can use instead of concat that makes it more readable. https://github.com/ReactiveX/rxjs/pull/3679

like image 72
martin Avatar answered Oct 17 '25 22:10

martin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!