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
rxjsuses classes, where@lirx/coreuses functions. So the classObservablebecomes the type IObservable (a function definition). The same is true forObserver=> IObserver.rxjsregroups under the same name (Operator), the functions that generate an Observable, and the pipes that chains them (calledPipeable Operator).@lirx/corehas 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