Emitters
Emitters are fundamental units of communication in the reactive store. They enable straightforward creation and management of reactive streams, integrating seamlessly with other reactive sources like emitters, states, and observables. This integration allows you to build complex networks of streams and effectively manage reactive data flows.
Creating an Emitter
Basic Emitter
To create Emitter, use the emitter function:
import {emitter} from '@bitfiber/rx';
const counter = emitter<number>();
Emitter with Interaction Logic
To add interaction logic with other reactive sources, use the onInit
callback. This ensures
subscriptions and emissions occur only after the store is initialized:
const receiver = emitter<number>(e => e
// Add interaction logic here
.receive(source));
const source = emitter<number>();
Emitting Data
Emitters allow you to send data to their subscribers, effects, and any connected reactive sources using the emit method:
const token = emitter<string>();
token.emit('token');
Receiving Data
Emitters can receive data from various reactive sources like emitters, states, and observables, transmitting it to subscribers without storing the data.
Methods for Receiving Data
- receive method
Emitters can receive data from other reactive sources using the receive
method.
Without Data Transformation
import {of} from 'rxjs';
import {emitter, state} from '@bitfiber/rx';
const source1 = emitter<number>();
const source2 = state<number>(1);
const source3$ = of(1);
const receiver = emitter<number>(e => e
.receive(source1, source2, source3$));
With Data Transformation
const receiver = emitter<string>(e => e
.receive(source1, value => String(value)));
- select method
Combines data from all sources and emits a computed value whenever any source emits:
const receiver = emitter<number>(e => e
.select(source1, source2, source3$, (v1, v2, v3) => v1 * v2 * v3));
- zip method
Combines data from all sources, emitting only when all sources emit new values:
const receiver = emitter<number>(e => e
.zip(source1, source2, source3$, (v1, v2, v3) => v1 * v2 * v3));
- wait method
Waits for the first values from all sources, emits a computed value, and completes the stream:
const receiver = emitter<number>(e => e
.wait(source1, source2, source3$, (v1, v2, v3) => v1 * v2 * v3));
Working with Observables
Emitters can receive data from observables, which allows you to use RxJS operators for more advanced stream manipulation before connecting them to emitters.
import {debounceTime, filter} from 'rxjs';
import {emitter} from '@bitfiber/rx';
const source = emitter<number>();
// The '$' property returns the emitter observable
const source$ = source.$.pipe(
filter(v => v % 2),
debounceTime(500),
);
const receiver = emitter<number>(e => e
.receive(source$));
Transmitting Data
Emitters can transmit their emitted values to other reactive sources using the transmit method.
Without Data Transformation
import {Subject} from 'rxjs';
import {emitter, state} from '@bitfiber/rx';
const source = emitter<number>(e => e
.transmit(receiver1, receiver2, receiver3));
const receiver1 = emitter<number>();
const receiver2 = state<number>(0);
const receiver3 = new Subject<number>();
With Data Transformation
import {emitter, state} from '@bitfiber/rx';
const source = emitter<string>(e => e
.transmit(receiver, (value, state) => state + Number(value)));
const receiver = state<number>(0);
Creating Side Effects
Emitters support creating side effects using tap and effect methods.
Using Tap
The tap
method performs a side effect whenever the emitter emits a value.
import {emitter} from '@bitfiber/rx';
const logger = emitter<number>(e => e
.tap(data => console.log(data)));
Using Effect
The effect
method allows for complex stream management using RxJS operators.
import {debounceTime, filter, switchMap} from 'rxjs';
import {emitter} from '@bitfiber/rx';
const productReq = emitter<number | null>(e => e
.effect(
filter(id => id !== null),
debounceTime(1000),
switchMap(id => productsService.get(`api/product${id}`)),
));
Managing All Streams
Emitters allow you to apply RxJS operators across all their streams simultaneously using the manage method. This ensures consistent stream behavior by applying the same operators to all streams generated by the emitter.
import {delay, filter} from 'rxjs';
import {emitter} from '@bitfiber/rx';
// Creates an emitter with managed streams
const id = emitter<number>(e => e
// Applies operators to all streams of this emitter
.manage(
// Filters values to pass only odd numbers
filter(id => !!(id % 2)),
// Adds a delay to all emissions
delay(100),
));