Skip to content

Commit

Permalink
feat(ofType): add operator to provided actions observable
Browse files Browse the repository at this point in the history
This adds an `ofType` operator to the actions observable provided to the dispatched function that will be available anywhere
in the operator chain for that observable. It basically filters by the action's type, which is a common need.
  • Loading branch information
benlesh committed May 12, 2016
1 parent ab33766 commit 174ceda
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
19 changes: 19 additions & 0 deletions src/actions-observable.js
@@ -0,0 +1,19 @@
import { Observable } from 'rxjs/Observable';
import { filter } from 'rxjs/operator/filter';

export class ActionsObservable extends Observable {
constructor(actionsSubject) {
super();
this.source = actionsSubject;
}

lift(operator) {
const observable = new ActionsObservable(this);
observable.operator = operator;
return observable;
}

ofType(key) {
return this::filter((action) => action.type === key);
}
}
6 changes: 5 additions & 1 deletion src/index.js
@@ -1,13 +1,15 @@
import { Subject } from 'rxjs/Subject';
import { from } from 'rxjs/observable/from';
import { ActionsObservable as Actions } from './actions-observable';

export function reduxObservable() {
let actions = new Subject();
let actionsObs = new Actions(actions);

let middleware = (store) => (next) => {
return (action) => {
if (typeof action === 'function') {
let obs = from(action(actions, store));
let obs = from(action(actionsObs, store));
let sub = obs.subscribe(next);
return sub;
} else {
Expand All @@ -19,3 +21,5 @@ export function reduxObservable() {

return middleware;
}

export const ActionsObservable = Actions;
51 changes: 51 additions & 0 deletions test/actions-observable-spec.js
@@ -0,0 +1,51 @@
/* globals describe it */
import { expect } from 'chai';
import { ActionsObservable, reduxObservable } from '../';
import { createStore, applyMiddleware } from 'redux';
import { of } from 'rxjs/observable/of';
import { Subject } from 'rxjs/Subject';

describe('ActionsObservable', () => {
it('should exist', () => {
expect(ActionsObservable).to.be.a('function');
});

it('should be the type provided to a dispatched function', () => {
let middleware = reduxObservable();
let reducer = (state, action) => {
return state;
};

let store = createStore(reducer, applyMiddleware(middleware));

store.dispatch((arg1) => {
expect(arg1).to.be.an.instanceof(ActionsObservable);
return of({ type: 'WEEE' });
});
});

it('should have a ofType operator that filters by action type', () => {
let actions = new Subject();
let actionsObs = new ActionsObservable(actions);
let lulz = [];
let haha = [];

actionsObs.ofType('LULZ').subscribe(x => lulz.push(x));
actionsObs.ofType('HAHA').subscribe(x => haha.push(x));

actions.next({ type: 'LULZ', i: 0 });

expect(lulz).to.deep.equal([{ type: 'LULZ', i: 0 }]);
expect(haha).to.deep.equal([]);

actions.next({ type: 'LULZ', i: 1 });

expect(lulz).to.deep.equal([{ type: 'LULZ', i: 0 }, { type: 'LULZ', i: 1 }]);
expect(haha).to.deep.equal([]);

actions.next({ type: 'HAHA', i: 0 });

expect(lulz).to.deep.equal([{ type: 'LULZ', i: 0 }, { type: 'LULZ', i: 1 }]);
expect(haha).to.deep.equal([{ type: 'HAHA', i: 0 }]);
});
});

0 comments on commit 174ceda

Please sign in to comment.