Migrating from RxJS
Migrating from rxjs
to @lirx/core
is a great choice if you aim to improve globally your applications:
⚡ it strongly improves the performances and reduce the overall size.
📑 it comes with a clear documentation, including direct references to the rxjs
's equivalent if one exists.
In consequence, you'll never get lost.
🪄 it's simpler by design, and the power of Observable sending data instead of states (no comeplete
or error
to manage),
reduces the complexity of some elaborated pipes or aggregators like switchMap
, mergeAll
, etc...
Using exclusively @lirx/core
in replacement of rxjs
is therefore good option,
especially in new applications.
For already existing applications, we recommend to slowly replace your old rxjs
's Observables with the @lirx/core
's ones.
This documentation is here to help you in this migration 🏗️
Bridge
To convert from the rxjs
's Observables to the @lirx/core
's one you can use the bridge.
Installation
- npm
- Yarn
npm install @lirx/rxjs-bridge --save
yarn add @lirx/rxjs-bridge
The installation requires rxjs
as a peer dependency.
Functions
I guess they speak for themselves.
Types
rxjs
uses classes, where@lirx/core
uses functions. So the classObservable
becomes the type IObservable (a function definition). The same is true forObserver
=> IObserver.rxjs
regroups under the same name (Operator
), the functions that generate an Observable, and the pipes that chains them (calledPipeable Operator
).@lirx/core
has a specific type for the pipes: IObservablePipe.
Moreover, @lirx/core
tries to be more consistent in its naming:
- functions are explicit about what they return. For example, if a function returns an IObservablePipe, then it will end with
ObservablePipe
. - it follows the Observable naming convention: a
$
is present at the end of a variable name representing an Observable (ex:const value$ = of(5);
), and it extends this rule with$$
for a function that generates an Observable, and$$$
for a function that generates an ObservablePipe.
Creating an Observable
Most functions that create an Observable in rxjs
have a similar name in @lirx/core
. Example:
- of
- fromEventTarget
- combineLatest
- interval
- etc...
However, a few may diverge, in their arguments, naming, or internal logic (especially when working with notifications).
Creating an ObservablePipe
The same is true for the Observable pipes:
- distinct$$$
- map$$$
- scan$$$
- debounceTime$$$
- etc...
Subscription / Unsubscription
To subscribe with rxjs
, we have to call the subscribe
method, which returns a Subscription.
Later we can unsubscribe it, using the method unsubscribe
:
const subscription = of(1, 2, 3)
.subscribe((value: number) => {
console.log(value);
});
// LATER
subscription.unsubscribe();
With @lirx/core
we just have to call a function, and next call its return:
const unsubscribe = of(1, 2, 3)
((value: number) => {
console.log(value);
});
// LATER
unsubscribe();
This simple trick allows @lirx/core
to heavily optimize function calls and code.
Piping
With rxjs
we pipe our Observables with the method pipe
:
const subscription = of(1, 2, 3)
.pipe(
map(String),
distinct(),
);
With @lirx/core
, instead of using a method, we'll use the function pipe$$;
const subscription = pipe$$(of(1, 2, 3), [
map$$$(String),
distinct$$$(),
]);
If we only have one pipe, we can even inline it:
const subscription = map$$(of(1, 2, 3), String);
It will improve the performances and bundle size.
State of the Observable - next, complete and error
The @lirx/core
Observables don't have a complete
nor error
state. Instead, they just send values defined by their type.
This is somehow, like if they were only sending next
. To send a state, we have to use some Notifications.
Subject, BehaviorSubject and ReplaySubject
They are replaced by Sources:
- Subject: createMulticastSource
- BehaviorSubject: createMulticastReplayLastSource
- ReplaySubject: createMulticastReplaySource