Skip to content

Instantly share code, notes, and snippets.

@newtriks
Last active Sep 5, 2018
Embed
What would you like to do?
Playing with immutable state using RxJS
import {List, Record, toJS} from 'immutable';
import Rx, {Observable, Subject} from 'rx';
const initialState = Record({count: 0, text: '', items: List(), history: List(), future: List()});
const subject = new Subject();
const source = Observable.merge(subject)
.scan((currentState, action) => action(currentState), initialState());
source.subscribe(
state => {
console.log('Next: %s', JSON.stringify(state.toJS()));
},
err => {
console.log('Error: %s', err);
},
() => {
console.log('Completed');
});
function incrementCount(n) {
return state => state.update('count', c => c + n);
}
function setText(str) {
return state => state.set('text', str);
}
function addItem(item) {
return state => state.update('items', list => list.push(item))
.update('history', list => list.push(state.items));
}
function removeItem(item_id) {
return state => state.update('items', list => list.filter(({id}) => item_id !== id))
.update('history', list => list.push(state.items));
}
function undo() {
return state => state.update('items', list => state.history.last())
.update('future', list => list.push(state.items))
.update('history', list => list.pop());
}
function redo() {
return state => state.update('items', list => state.future.last())
.update('future', list => list.pop())
.update('history', list => list.push(state.items));
}
subject.onNext(incrementCount(1)); // => Next: {"count":1,"text":"","items":[]}
subject.onNext(incrementCount(1)); // => Next: {"count":2,"text":"","items":[]}
subject.onNext(setText('foo')); // => Next: {"count":2,"text":"foo","items":[]}
subject.onNext(addItem({emcee: 'Busdriver', id: '1'})); // => Next: {"count":2,"text":"foo","items":[{"emcee":"Busdriver","id":"1"}]}
subject.onNext(addItem({emcee: 'Aceyalone', id: '2'})); // => Next: {"count":2,"text":"foo","items":[{"emcee":"Busdriver","id":"1"},{"emcee":"Aceyalone","id":"2"}]}
subject.onNext(removeItem('1')); // => Next: {"count":2,"text":"foo","items":[{"emcee":"Aceyalone","id":"2"}]}
subject.onNext(undo()); // => Next: {"count":2,"text":"foo","items":[{"emcee":"Busdriver","id":"1"},{"emcee":"Aceyalone","id":"2"}],"history":[[],[{"emcee":"Busdriver","id":"1"}]]}
subject.onNext(redo()); // => Next: {"count":2,"text":"foo","items":[{"emcee":"Aceyalone","id":"2"}],"history":[[],[{"emcee":"Busdriver","id":"1"}],[{"emcee":"Busdriver","id":"1"},{"emcee":"Aceyalone","id":"2"}]],"future":[]}
subject.onCompleted(); // => Completed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment