Category Archives: reactive

RxJS process loop with toggled operations and canceling

How to create a stream on a button that toggles between two operations, and another button that can cancel the same stream? Observable operators are numerous and very complex, so coming up with a solution, or composing a stream, to any problem can be very difficult. At least, that is what I found while learning all this reactive stuff.

Use case
UI:
Two buttons: one labeled “Start”, and another labeled “Exit”.

Behavior:
First click on ‘Start’ button, changes its label to “Toggle” and starts the operational loop that invokes operation1.

Further click on button, now labeled “Toggle”, will change the operation invoked alternatively to operation2 or operation1.

A click on the ‘Exit’ button will stop the loop stream.

Here is the RxJS based solution running in JS Bin playground: (Ability to re-run is not implemented. ‘Exit’ means you closed the app.)
RxJS toggable and cancellable process loop on jsbin.com

Sure, this would have been much easier with just regular JavaScript. Just create a timer and a listener on each button, etc. Observable streams don’t really add any value for this simple scenario. But, this is just a learning exercise.

Then again, using streams may offer more opportunities for handling more complex scenarios with timer loops.

Similar
This appears to be just like the very basic traditional state machine exercise of modeling a stopwatch. There, the toggle button starts/stops the timer, and the Exit is the cancel button. Do a web image search for “statechart stopwatch”.

Jump to source code

Solution
This seems easy now, but it took a lot to come up with a solution. The approach selected, using ‘scan’ was suggested in an article and a StackOverflow question. ‘Scan’ can be used to transfer statefulness.

For the loop we can create streams using timer or interval.

The alternation of operation is where the complexity comes in. “case” operator is very powerful since it can choose an Observable based on a key into a sources map. Would be useful if the operations, i.e., functions invoked in the loop, are themselves streams or Subjects.

If there is only one operation to execute in the loop and the toggle button is behaviorally a run/pause, then there is the “pausable” operator.

One thing I did not implement is a way to restart the process after it was exited. Do the whole thing as a programmatic setup on first start click, or figure out how to resubscribe to the observables? Oh well.

Software used
RxJS: version 4.0.7, rx.all.compat.js
JQuery 2.2.0: jquery-2.2.0.js

Links


Source
Two versions shown below, ES6 using arrow function expressions, and one using plain functions. I’m sure this is a naive newbie solution to this, so be very skeptical of the RxJS usage here. Note: I named the streams with a “$” prefix. a kind of reverse Hungarian Notation. This is a naming convention used by the Cycle.js project.

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.