Skip to content

Switch

Rx.switcher generates several independent output streams. Values from source are fed to the output streams if their associated predicate function returns true.

In this way, we can split one input stream into several output streams, each potentially getting a different subset of the input.

The below example shows setting up a switcher and consuming the output streams. Changes are directed to one of two output reactives based on whether the number is odd or even.

// Initialise a reactive number, starting at 0
const switcherSource = Rx.number(0);
// Create a switcher reactive
const rxS = Rx.switcher(switcherSource, {
even: v => v % 2 === 0,
odd: v => v % 2 !== 0
});

rxS will be an object consisting of several reactives:

type rxS = {
even: Reactive<number>
odd: Reactive<number>
}

Note the reactives are labelled by the property key. These labels are whatever is used when providing the predicates to Rx.switcher.

We can subscribe to each reactive, or do whatever else:

// Listen for outputs from each of the resulting streams
rxS.even.on(msg => {
log(`even: ${msg.value}`);
});
rxS.odd.on(msg => {
log(`odd: ${msg.value}`);
})

If we call switcherSource.set() with an odd number, this will be routed to a reactive labelled odd, or otherwise it will be routed to the even reactive.

By default the switcher only sends values to the first matching predicate. We can provide match: all as an option to send values to all matching predicates.

const rxS = Rx.switcher(switcherSource, {
even: v => v % 2 === 0,
odd: v => v % 2 !== 0
}, { match: `all` });

Example

Here’s a more practical example of switcher. In this case, detecting single or double-clicks.

// Listen for click events
const btnClicks = Rx.event(document.getElementById(`btnClick`), `click`);
// Collect clicks over a 200ms period
const btnClicksChunk = Rx.chunk(btnClicks, { elapsed: 200});
// Emit to one of three streams depending on number of
// clicks in a 200ms timeframe
const btnClickSwitch= Rx.switcher(btnClicksChunk, {
single: v=> v.length == 1,
double: v=> v.length == 2,
more: v=>v.length > 2
});
// eg.
btnClickSwitch.double.on(msg => {
console.log(`double click!`);
});