Deprecated APIs in RxJS v7
This page documents all APIs that are deprecated in RxJS v7. These APIs still work but will be removed in RxJS v8. Migrate to the recommended alternatives as soon as possible.
Promise Conversion
toPromise()
Deprecated in v7, will be removed in v8 . Use firstValueFrom() or lastValueFrom() instead.
The toPromise() method has been deprecated because:
The name doesn’t indicate which value (first or last) will be used
The return type Promise<T | undefined> can be confusing
The behavior with empty observables is inconsistent
Migration to lastValueFrom
Use lastValueFrom() when you want the final emitted value:
toPromise() - Deprecated
lastValueFrom() - Recommended
import { interval } from 'rxjs' ;
import { take } from 'rxjs/operators' ;
async function example () {
const source$ = interval ( 1000 ). pipe ( take ( 5 ));
const result = await source$ . toPromise ();
console . log ( result ); // 4 (last value)
}
Migration to firstValueFrom
Use firstValueFrom() when you want the first emitted value:
When you want first value
firstValueFrom() - Better
import { interval } from 'rxjs' ;
import { map } from 'rxjs/operators' ;
async function example () {
// With toPromise, you'd need take(1)
const source$ = interval ( 1000 ). pipe (
map ( x => x * 2 ),
take ( 1 )
);
const result = await source$ . toPromise ();
console . log ( result ); // 0
}
Handling Empty Observables
EmptyError vs. default values
toPromise() behavior
lastValueFrom with default
firstValueFrom with default
import { EMPTY } from 'rxjs' ;
async function example () {
const result = await EMPTY . toPromise ();
console . log ( result ); // undefined
}
Warning : Only use these functions with observables that will complete. For potentially infinite observables, add timeout, take, takeWhile, or takeUntil to prevent memory leaks.
Subscribe Arguments
Multiple Function Arguments
Deprecated in v6.4, will be removed in v8 . Use observer objects instead of multiple function arguments.
Passing multiple function arguments to subscribe() is deprecated. This affects both subscribe() and the tap operator.
Why This Was Deprecated
Readability : subscribe(doSomething, doSomethingElse, lol) is unclear
Future flexibility : Second argument may be used for configuration (AbortSignal, etc.)
Null confusion : subscribe(null, null, onComplete) is hard to read
Migration Examples
Deprecated - All callbacks
Recommended - Observer object
import { of } from 'rxjs' ;
of ( 1 , 2 , 3 ). subscribe (
value => console . log ( value ),
err => console . error ( err ),
() => console . log ( 'complete' )
);
Deprecated - Error only
Recommended - Error only
import { throwError } from 'rxjs' ;
throwError (() => new Error ( 'oops' )). subscribe (
null ,
err => console . error ( err )
);
Deprecated - Complete only
Recommended - Complete only
import { EMPTY } from 'rxjs' ;
EMPTY . subscribe (
null ,
null ,
() => console . log ( 'complete' )
);
Single next callback is still fine : of(1, 2, 3).subscribe(v => console.log(v)) is the recommended pattern when you only need the next callback.
tap Operator
The same deprecation applies to tap:
import { of } from 'rxjs' ;
import { tap } from 'rxjs/operators' ;
of ( 1 , 2 , 3 ). pipe (
tap (
v => console . log ( 'next:' , v ),
err => console . error ( 'error:' , err ),
() => console . log ( 'complete' )
)
). subscribe ();
Multicasting APIs
Deprecated in v7, will be removed in v8 . Multicasting APIs have been simplified to connectable, connect, and share.
ConnectableObservable
Deprecated
Recommended - connectable
Recommended - share with refCount
import { ConnectableObservable , timer , Subject } from 'rxjs' ;
const tick$ = new ConnectableObservable (
timer ( 1000 ),
() => new Subject ()
);
tick$ . connect ();
multicast
multicast with subject factory
import { timer , multicast , Subject , ConnectableObservable } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
multicast (() => new Subject ())
) as ConnectableObservable < number >;
tick$ . connect ();
multicast with subject instance
import { timer , multicast , Subject , ConnectableObservable } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
multicast ( new Subject ())
) as ConnectableObservable < number >;
tick$ . connect ();
import { timer , multicast , Subject , refCount } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
multicast (() => new Subject ()),
refCount ()
);
import { timer , multicast , Subject , combineLatest } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
multicast (
() => new Subject (),
source => combineLatest ([ source , source ])
)
);
publish Variants
Deprecated
Recommended - connectable
Recommended - share with refCount
import { timer , publish , ConnectableObservable } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
publish ()
) as ConnectableObservable < number >;
tick$ . connect ();
Deprecated
Recommended
Recommended - with refCount
import { timer , publishBehavior , ConnectableObservable } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
publishBehavior ( 0 )
) as ConnectableObservable < number >;
tick$ . connect ();
import { timer , publishLast , ConnectableObservable } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
publishLast ()
) as ConnectableObservable < number >;
tick$ . connect ();
Deprecated
Recommended
Alternative - shareReplay
import { timer , publishReplay , ConnectableObservable } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
publishReplay ( 2 )
) as ConnectableObservable < number >;
tick$ . connect ();
refCount
import { timer , publish , refCount } from 'rxjs' ;
const tick$ = timer ( 1000 ). pipe (
publish (),
refCount ()
);
Scheduler Argument
Deprecated in v6.5, will be removed in v8 . Use scheduled() function instead of scheduler arguments.
Affected Operators
from, of, merge, concat
startWith, endWith
combineLatest
Migration to scheduled
Deprecated - of
Recommended - scheduled
import { of , asyncScheduler } from 'rxjs' ;
of ( 1 , 2 , 3 , asyncScheduler ). subscribe ( console . log );
Deprecated - from
Recommended - scheduled
import { from , asyncScheduler } from 'rxjs' ;
from ([ 1 , 2 , 3 ], asyncScheduler ). subscribe ( console . log );
import { concat , of , asyncScheduler } from 'rxjs' ;
concat (
of ( 'hello' ),
of ( 'world' ),
asyncScheduler
). subscribe ( console . log );
import { merge , of , asyncScheduler } from 'rxjs' ;
merge (
of ( 1 , 2 ),
of ( 3 , 4 ),
asyncScheduler
). subscribe ( console . log );
import { combineLatest , of , asyncScheduler } from 'rxjs' ;
combineLatest (
of ( 'hello' ),
of ( 'world' ),
asyncScheduler
). subscribe ( console . log );
ResultSelector Parameter
Deprecated in v6.0, will be removed in v8 . Use map operator instead of resultSelector parameter.
Why It Was Deprecated
Increases bundle size for every operator
Can cause memory pressure by retaining values
Same functionality available via map
Affected Operators
concatMap, concatMapTo
exhaustMap
mergeMap, mergeMapTo
switchMap, switchMapTo
Migration Examples
Deprecated - switchMap
Recommended - map
import { fromEvent , switchMap , interval } from 'rxjs' ;
fromEvent ( document , 'click' ). pipe (
switchMap (
() => interval ( 1000 ),
( outer , inner ) => inner + 1 // resultSelector
)
). subscribe ( console . log );
Deprecated - mergeMap
Recommended - map
import { of , mergeMap } from 'rxjs' ;
of ( 1 , 2 , 3 ). pipe (
mergeMap (
x => of ( x * 10 ),
( outer , inner ) => ({ outer , inner }) // resultSelector
)
). subscribe ( console . log );
Array Arguments
Deprecated in v6.5 . Pass arrays or objects instead of multiple arguments.
Affected Operators
Migration Examples
Deprecated
Recommended - Array
Recommended - Object
import { forkJoin , of } from 'rxjs' ;
const odd$ = of ( 1 , 3 , 5 );
const even$ = of ( 2 , 4 , 6 );
forkJoin ( odd$ , even$ ). subscribe ( console . log );
Deprecated - combineLatest
Recommended - Array
Recommended - Object
import { combineLatest , of } from 'rxjs' ;
combineLatest (
of ( 1 ),
of ( 'a' ),
of ( true )
). subscribe ( console . log );
Deprecated Operators
concat, merge, zip, race (Pipeable)
The pipeable versions of concat, merge, zip, and race are deprecated. Use the new -With variants.
import { of } from 'rxjs' ;
import { concat , merge , zip , race } from 'rxjs/operators' ;
of ( 1 ). pipe ( concat ( of ( 2 ))). subscribe ();
of ( 1 ). pipe ( merge ( of ( 2 ))). subscribe ();
of ( 1 ). pipe ( zip ( of ( 2 ))). subscribe ();
of ( 1 ). pipe ( race ( of ( 2 ))). subscribe ();
Migration Timeline
RxJS v6.4 (2019)
Subscribe arguments deprecated
RxJS v6.5 (2019)
Scheduler arguments deprecated
Array arguments pattern introduced
ResultSelector deprecated
RxJS v7 (2021)
All v6 deprecations still functional
toPromise() deprecated
Multicasting APIs deprecated
New replacement APIs introduced
RxJS v8 (Future)
All deprecated APIs will be removed
Quick Reference
Deprecated API Replacement Version toPromise()firstValueFrom() / lastValueFrom()v7 → v8 subscribe(fn, fn, fn)subscribe({ next, error, complete })v6.4 → v8 multicast()connectable() / share()v7 → v8 publish()connectable() / share()v7 → v8 publishBehavior()connectable() with BehaviorSubjectv7 → v8 publishLast()connectable() with AsyncSubjectv7 → v8 publishReplay()connectable() / shareReplay()v7 → v8 refCount()share()v7 → v8 of(..., scheduler)scheduled([...], scheduler)v6.5 → v8 resultSelector parametermap() operatorv6.0 → v8 combineLatest(a, b)combineLatest([a, b])v6.5 → v8 concat operatorconcatWithv7 → v8 merge operatormergeWithv7 → v8 zip operatorzipWithv7 → v8 race operatorraceWithv7 → v8
Additional Resources