This document contains a detailed list of changes between RxJS 6.x and RxJS 7.x, presented in the order they can be found when diffing the TypeScript APIs in various module files.
_subscribe
method is no longerpublic
and is nowprotected
.- no longer has its own implementation of the
error
method inherited fromSubject
.
_subscribe
method is no longerpublic
and is nowprotected
.value
property is a getterget value()
instead ofreadonly value
, and can no longer be forcibly set.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
_isComplete
is no longer a property._subscribe
method is no longerpublic
and is nowprotected
.
- Generic argument no longer extends
void
. defer
no longer allows factories to return void or undefined. All factories passed todefer
must return a properObservableInput
, such asObservable
,Promise
, et al. To get the same behavior as you may have relied on previously,return EMPTY
orreturn of()
from the factory.
- Generic signatures have changed. Do not explicitly pass generics.
- The
fromEvent
signatures have been changed and there are now separate signatures for each type of target - DOM, Node, jQuery, etc. That means that an attempt to pass options - like{ once: true }
- to a target that does not support an options argument will result in a TypeScript error.
- No longer publicly exposes
_subscribe
key
properly isreadonly
.- No longer publicly exposes
constructor
.
- Generic signatures have changed. Do not explicitly pass generics.
iif
will no longer allow result arguments that areundefined
. This was a bad call pattern that was likely an error in most cases. If for some reason you are relying on this behavior, simply substituteEMPTY
in place of theundefined
argument. This ensures that the behavior was intentional and desired, rather than the result of an accidentalundefined
argument.
- No longer has a generic and returns
Observable<unknown>
, you must cast the result.
- Generic signatures have changed. Do not explicitly pass generics.
- The
error
property is nowreadonly
. - The
hasValue
property is nowreadonly
. - The
kind
property is nowreadonly
. - The
value
property is nowreadonly
and may beundefined
. constructor
signature now only allows valid construction. For examplenew Notification('C', 'some_value')
will be an error in TypeScript.
_isScalar
property removed._subscribe
method is no longerpublic
and is now marked@internal
._trySubscribe
method is no longerpublic
and is now@internal
.pipe
method calls with9
or more arguments will now returnObservable<unknown>
rather thanObservable<{}>
.toPromise
method now correctly returnsPromise<T | undefined>
instead ofPromise<T>
. This a correction without a runtime change, because if the observable does not emit a value before completion, the promise will resolve withundefined
.static if
andstatic throw
properties are no longer defined. They were unused in version 6.lift
,source
, andoperator
properties are still deprecated, and should not be used. They are implementation details, and will very likely be renamed or missing in version 8.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
pairs
will no longer function in IE without a polyfill forObject.entries
.pairs
itself is also deprecated in favor of users just usingfrom(Object.entries(obj))
.
- Generic signatures have changed. Do not explicitly pass generics.
- Calls with
9
or more arguments will now return(arg: A) => unknown
rather than(arg: A) => {}
.
- Generic signatures have changed. Do not explicitly pass generics.
race
will no longer subscribe to subsequent observables if a provided source synchronously errors or completes. This means side effects that might have occurred during subscription in those rare cases will no longer occur.
_getNow
method has been removed._subscribe
method is no longerpublic
and is nowprotected
.
subscribe
will acceptPartial<Observer<T>>
now. All overloads with functions as arguments have been removed. This is becauseSubscribable
is intended to map to the basic observable contract from the TC39 proposal and the the return type of a call to[Symbol.observable]()
.
- See notes on
Subscribable
above.
destination
property must now be aSubscriber
or fullObserver
.syncErrorThrowable
property has been removed.syncErrorThrown
property has been removed.syncErrorValue
property has been removed._unsubscribeAndRecycle
method has been removed.
_parentOrParents
property has been removed.add
method returnsvoid
and no longer returns aSubscription
. ReturningSubscription
was an old behavior from the early days of version 5. If you add a function to a subscription (i.e.subscription.add(fn)
), you can remove that function directly by callingremove
with the same function instance. (i.e.subscription.remove(fn)
). Previously, you needed to get the returnedSubscription
object and pass that toremove
. In version 6 and lower, theSubscription
returned by callingadd
with anotherSubscription
was always the same subscription you passed in. (meaningsubscription.add(subs1).add(subs2)
was an antipattern and the same assubscription.add(subs1); subs1.add(subs2);
.
- The static
sortActions
method has been removed.
- Generic signatures have changed. Do not explicitly pass generics.
- Zipping a single array will now have a different result. This is an extreme corner-case, because it is very unlikely that anyone would want to zip an array with nothing at all. The workaround would be to wrap the array in another array
zip([[1,2,3]])
. But again, that's pretty weird.
- A new method for creating a stream of animation frames. Each event will carry with it a high-resolution timestamp, and an elapsed time since observation was started.
- A handler for dealing with errors that make it all the way down to the "end" of the observation chain when there is no error handler in the observer. Useful for doing things like logging unhandled errors in RxJS observable chains.
- A handler for edge cases where a subscriber within RxJS is notified after it has already "stopped", that is, a point in time where it has received an error or complete, but hasn't yet finalized. This is mostly useful for logging purposes.
- In RxJS 6, a little used feature allowed users to access the
subscriber
directly asthis
within a call to thenext
handler. The problem with this is it incurred heavy performance penalties. That behavior has been changed (because it wasn't really documented and it was barely ever used) to not change thethis
context of any user-provided subscription handlers. If you need to get that feature back, you can switch it on with this flag. Note this behavior will be removed completely in version 8.
- This is the new means for creating a
ConnectableObservable
, and really us a replacement for non-selector usage ofmulticast
andpublish
variants. Simply pass your source observable toconnectable
with theSubject
you'd like to connect through.
- A better, more tree-shakable replacement for
toPromise()
(which is now deprecated). This function allows the user to convert anyObservable
in to aPromise
that will resolve when the source observable emits its first value. If the source observable closes without emitting a value, the returned promise will reject with anEmptyError
, or it will resolve with a configureddefaultValue
.
- This is just a type, but it's important. This type defines the allowed types that can be passed to almost every API within RxJS that accepts an Observable. It has always accepted
Observable
,Promise
,Iterable
, andArrayLike
. Now it will also acceptAsyncIterable
andReadableStream
.
AsyncIterables
such as those defined byIxJS
or by async generators (async function*
), may now be passed to any API that accepts an observable, and can be converted to anObservable
directly usingfrom
.
ReadableStream
such as those returned byfetch
, et al, can be passed to any API that accepts an observable, and can be converted toObservable
directly usingfrom
.
- A bug was fixed that prevented a completed or errored
ReplaySubject
from accumulating values in its buffer when resubscribed to another source. This breaks some uses - like this StackOverflow answer - that depended upon the buggy behavior.
- Now allows adding and removing of functions directly via
add
andremove
methods.
- Now accepts an
errorFactory
of() => any
to defer the creation of the error until the time it will be emitted. It is recommended to use this method, as Errors created in most popular JavaScript runtimes will retain all values in the current scope for debugging purposes.
- The observable returned by the
audit
operator's duration selector must emit a next notification to end the duration. Complete notifications no longer end the duration. audit
now emits the last value from the source when the source completes. Previously,audit
would mirror the completion without emitting the value.
auditTime
now emits the last value from the source when the source completes, after the audit duration elapses. Previously,auditTime
would mirror the completion without emitting the value and without waiting for the audit duration to elapse.
buffer
now subscribes to the source observable before it subscribes to the closing notifier. Previously, it subscribed to the closing notifier first.- Final buffered values will now always be emitted. To get the same behavior as the previous release, you can use
endWith
andskipLast(1)
, like so:source$.pipe(buffer(notifier$.pipe(endWith(true))), skipLast(1))
closingNotifier
completion no longer completes the result ofbuffer
. If that is truly a desired behavior, then you should usetakeUntil
. Something like:source$.pipe(buffer(notifier$), takeUntil(notifier$.pipe(ignoreElements(), endWith(true))))
, wherenotifier$
is multicast, although there are many ways to compose this behavior.
- The observable returned by the
bufferToggle
operator's closing selector must emit a next notification to close the buffer. Complete notifications no longer close the buffer.
- The observable returned by the
bufferWhen
operator's closing selector must emit a next notification to close the buffer. Complete notifications no longer close the buffer.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
- Still deprecated, use the new
concatWith
.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
- No longer passes
source
observable as a third argument to the predicate. That feature was rarely used, and of limited value. The workaround is to simply close over the source inside of the function if you need to access it in there.
- The observable returned by the
debounce
operator's duration selector must emit a next notification to end the duration. Complete notifications no longer end the duration.
- Generic signatures have changed. Do not explicitly pass generics.
defaultIfEmpty
requires a value be passed. Will no longer convertundefined
tonull
for no good reason.
delayWhen
will no longer emit if the duration selector simply completes without a value. Notifiers must notify with a value, not a completion.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
finalize
will now unsubscribe from its source before it calls its callback. That means thatfinalize
callbacks will run in the order in which they occur in the pipeline:source.pipe(finalize(() => console.log(1)), finalize(() => console.log(2)))
will log1
and then2
. Previously, callbacks were called in the reverse order.
thisArg
will now default toundefined
. The previous default ofMapSubscriber
never made any sense. This will only affect code that calls map with afunction
and referencesthis
like so:source.pipe(map(function () { console.log(this); }))
. There wasn't anything useful about doing this, so the breakage is expected to be very minimal. If anything we're no longer leaking an implementation detail.
- Generic signatures have changed. Do not explicitly pass generics.
- Still deprecated, use the new
mergeWith
.
- Generic signatures have changed. Do not explicitly pass generics.
mergeScan
will no longer emit its inner state again upon completion.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
- The
sample
operator's notifier observable must emit a next notification to effect a sample. Complete notifications no longer effect a sample.
- Generic signatures have changed. Do not explicitly pass generics.
- The
single
operator will now throw for scenarios where values coming in are either not present, or do not match the provided predicate. Error types have thrown have also been updated, please check documentation for changes.
skipLast
will no longer error when passed a negative number, rather it will simply return the source, as though0
was passed.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
take
and will now throw runtime error for arguments that are negative or NaN, this includes non-TS calls liketake()
.
takeLast
now has runtime assertions that throwTypeError
s for invalid arguments. Calling takeLast without arguments or with an argument that isNaN
will throw aTypeError
.
- The observable returned by the
throttle
operator's duration selector must emit a next notification to end the duration. Complete notifications no longer end the duration.
- In an extreme corner case for usage,
throwError
is no longer able to emit a function as an error directly. If you need to push a function as an error, you will have to use the factory function to return the function like so:throwError(() => functionToEmit)
, in other wordsthrowError(() => () => console.log('called later'))
.
- The
windowBoundaries
observable no longer completes the result. It was only ever meant to notify of the window boundary. To get the same behavior as the old behavior, you would need to add anendWith
and askipLast(1)
like so:source$.pipe(window(notifier$.pipe(endWith(true))), skipLast(1))
.
- The observable returned by the
windowToggle
operator's closing selector must emit a next notification to close the window. Complete notifications no longer close the window.
- Generic signatures have changed. Do not explicitly pass generics.
- Generic signatures have changed. Do not explicitly pass generics.
- Still deprecated, use the new
zipWith
. zip
operators will no longer iterate provided iterables "as needed", instead the iterables will be treated as push-streams just like they would be everywhere else in RxJS. This means that passing an endless iterable will result in the thread locking up, as it will endlessly try to read from that iterable. This puts us in-line with all other Rx implementations. To work around this, it is probably best to usemap
or some combination ofmap
andzip
. For example,zip(source$, iterator)
could besource$.pipe(map(value => [value, iterator.next().value]))
.
- New operator to cover the use cases of
publish
variants that use aselector
. Wherein the selector allows the user to define multicast behavior prior to connection to the source observable for the multicast.
- Added functionality to allow complete configuration of what type of
Subject
is used to multicast, and when that subject is reset.
- Added more configuration options to
timeout
, so it could be used to timeout just if the first item doesn't arrive quickly enough, or it could be used as a timeout between each item. Users may also pass aDate
object to define an absolute time for a timeout for the first time to arrive. Adds additional information to the timeout error, and the ability to pass along metadata with the timeout for identification purposes.
- Simply renamed versions of the operators
zip
,concat
,mergeWith
, andrace
. So we can deprecate those old names and use the new names without collisions.
ajax
body serialization will now use default XHR behavior in all cases. If the body is aBlob
,ArrayBuffer
, any array buffer view (like a byte sequence, e.g.Uint8Array
, etc),FormData
,URLSearchParams
,string
, orReadableStream
, default handling is use. If thebody
is otherwisetypeof
"object"
, then it will be converted to JSON viaJSON.stringify
, and theContent-Type
header will be set toapplication/json;charset=utf-8
. All other types will emit an error.- The
Content-Type
header passed toajax
configuration no longer has any effect on the serialization behavior of the AJAX request. - For TypeScript users,
AjaxRequest
is no longer the type that should be explicitly used to create anajax
. It is nowAjaxConfig
, although the two types are compatible, onlyAjaxConfig
hasprogressSubscriber
andcreateXHR
. - Ajax implementation drops support for IE10 and lower. This puts us in-line with other implementations and helps clean up code in this area
AjaxRequest
is no longer used to type the configuration argument for calls toajax
. The new type isAjaxConfig
. This was done to disambiguate two very similar types with different use cases.AjaxRequest
is still there, but properties have changed, and it is used to show what final request information was send as part of an event response.
- Now includes
responseHeaders
. - Now includes event
type
andtotal
numbers for examining upload and download progress (seeincludeUploadProgress
andincludeDownloadProgress
).
- A flag to make a request that will include streaming upload progress events in the returned observable.
- A flag to make a request that will include streaming upload progress events in the returned observable.
- Configuration for setting query parameters in the URL of the request to be made.
xsrfCookieName
andxsrfHeaderName
were added for cross-site request forgery prevention capabilities.
No changes.
- A new means of comparing the equality of to observables. If all emissions are the same, and at the same time, then they are equal. This is primarily useful for refactoring operator chains and making sure that they are equivalent.