These tools help you work with many streams of data at once. They let you wait for multiple things to happen and then act on all results together.
combineLatest and forkJoin for combining in Angular
combineLatest([observable1, observable2, ...]) forkJoin([observable1, observable2, ...])
combineLatest emits new values whenever any input changes, but only after all have emitted at least once.
forkJoin waits for all inputs to complete, then emits the last value from each.
combineLatest([obs1, obs2]).subscribe(([val1, val2]) => {
console.log(val1, val2);
});forkJoin([obs1, obs2]).subscribe(([val1, val2]) => {
console.log(val1, val2);
});This Angular component shows how combineLatest updates whenever either observable emits, after both have emitted once. It also shows how forkJoin waits for both observables to finish and then emits their last values.
import { Component } from '@angular/core'; import { of, interval, combineLatest, forkJoin } from 'rxjs'; import { take, map } from 'rxjs/operators'; @Component({ selector: 'app-combine-example', template: ` <h2>combineLatest Output:</h2> <pre>{{ combineLatestOutput }}</pre> <h2>forkJoin Output:</h2> <pre>{{ forkJoinOutput }}</pre> ` }) export class CombineExampleComponent { combineLatestOutput = ''; forkJoinOutput = ''; constructor() { const obs1 = interval(1000).pipe( take(3), map(i => `A${i + 1}`) ); const obs2 = interval(1500).pipe( take(2), map(i => `B${i + 1}`) ); combineLatest([obs1, obs2]).subscribe(([val1, val2]) => { this.combineLatestOutput += `${val1} & ${val2}\n`; }); forkJoin([obs1, obs2]).subscribe(([val1, val2]) => { this.forkJoinOutput = `${val1} & ${val2}`; }); } }
combineLatest needs all observables to emit at least once before it starts emitting.
forkJoin only emits once, after all observables complete.
If any observable in forkJoin never completes, it will never emit.
combineLatest combines latest values and updates on any change.
forkJoin waits for all to finish and emits once.
Use combineLatest for live updates, forkJoin for final results.
Practice
combineLatest and forkJoin in Angular RxJS?Solution
Step 1: Understand
combineLatestbehaviorcombineLatestemits a new combined value whenever any source observable emits after all have emitted at least once.Step 2: Understand
forkJoinbehaviorforkJoinwaits for all source observables to complete and then emits a single combined array of their last emitted values.Final Answer:
combineLatestemits on any change;forkJoinemits once after all complete. -> Option CQuick Check:
combineLatest = live updates, forkJoin = final result [OK]
- Thinking forkJoin emits multiple times
- Confusing combineLatest with forkJoin completion behavior
- Assuming combineLatest waits for all to complete
combineLatest and forkJoin from RxJS in Angular?Solution
Step 1: Identify correct RxJS import path
BothcombineLatestandforkJoinare exported from the main 'rxjs' package, not from Angular core or operators.Step 2: Verify common incorrect imports
@angular/coreis Angular framework code,rxjs/operatorscontains operators like map, filter, but not these combinators.Final Answer:
import { combineLatest, forkJoin } from 'rxjs'; -> Option BQuick Check:
RxJS combinators import from 'rxjs' [OK]
- Importing from 'rxjs/operators' instead of 'rxjs'
- Importing from '@angular/core' by mistake
- Using internal RxJS paths which are not public API
import { of, combineLatest } from 'rxjs';
const obs1 = of(1, 2);
const obs2 = of('A', 'B');
combineLatest([obs1, obs2]).subscribe(console.log);Solution
Step 1: Understand
Bothofobservables emitting synchronouslyobs1andobs2emit their values immediately and complete.obs1emits 1 then 2;obs2emits 'A' then 'B'.Step 2: Analyze
combineLatestwith synchronous emissionscombineLatestwaits for all to emit at least once, then emits combined latest values on any emission. Since subscriptions are synchronous,obs1emits both values first (latest from obs1 is 2), thenobs2emits 'A' (triggers [2, 'A']), then 'B' (triggers [2, 'B']).Final Answer:
[2, 'A'], [2, 'B'] -> Option DQuick Check:
Synchronous combineLatest: last of first + all of second [OK]
- Thinking combineLatest emits only the final values once (forkJoin behavior)
- Thinking combineLatest emits all intermediate pairs
- Assuming no output because of immediate completion
forkJoin:
import { forkJoin, of } from 'rxjs';
const obs1 = of(1, 2);
const obs2 = of('A', 'B');
forkJoin([obs1, obs2]).subscribe(console.log);Solution
Step 1: Check forkJoin input and behavior
forkJoinaccepts an array of observables and waits for all to complete, then emits an array of their last emitted values.Step 2: Verify observables emitting multiple values
Observables emitting multiple values are allowed; forkJoin only emits after completion with last values. Here, obs1 emits 1 then 2, obs2 emits 'A' then 'B'. forkJoin emits [2, 'B'] once.Final Answer:
No error; code works and logs [2, 'B'] -> Option AQuick Check:
forkJoin waits for last values, no error [OK]
- Thinking forkJoin errors on multiple emissions
- Believing forkJoin emits multiple times
- Assuming forkJoin cannot take arrays
getUser() and getOrders(). You want to display user info immediately and update orders live as they change. Which combination should you use?Solution
Step 1: Understand HTTP observables behavior
HTTP calls likegetUser()usually emit once and complete. Orders may update live, sogetOrders()is likely a stream emitting multiple times.Step 2: Choose appropriate combinators
UseforkJoinforgetUser()to wait for the single response. UsecombineLatestforgetOrders()to get live updates. Then combine these appropriately (e.g., nest or switchMap) to show user info immediately and update orders live.Final Answer:
Use forkJoin for getUser() and combineLatest for getOrders() -> Option AQuick Check:
Single HTTP = forkJoin, live stream = combineLatest [OK]
- Using combineLatest for single HTTP call causing unnecessary updates
- Using forkJoin for live streams causing no updates after first emit
- Mixing combinators incorrectly causing delayed or missing data
Ready to prove it?
Pass the test and this pattern moves unknown
