Skip to content

angular-redux/redux-observable-decorator

Folders and files

NameName
Last commit message
Last commit date

Latest commit

author
James Salas
Jan 16, 2019
9b8b152 · Jan 16, 2019

History

50 Commits
Jan 16, 2019
Jan 5, 2019
Jan 5, 2019
Jan 5, 2019
Jan 16, 2019
Dec 21, 2016
Jan 5, 2019
Dec 21, 2016
Jan 5, 2019
Jan 5, 2019
Jan 16, 2019
Jan 5, 2019
Jan 5, 2019
Jan 5, 2019
Dec 21, 2016
Jan 5, 2019

Repository files navigation

CircleCI npm version npm downloads

redux-observable-decorator

Decorators for Redux Observable

When using Redux with Angular with angular-redux/store and redux-observable, it's common to create your epics as an injectable class, and when configuring the store - creating an epic middleware for each one, or using combineEpics:

@Injectable()
export class SomeEpics {
	epicOne = (action$) => action$.ofType('PING').pipe(mapTo({type: 'PONG'}));
	epicTwo = (action$) => action$.ofType('ACTION_IN').pipe(mapTo({type: 'ACTION_OUT'}));
}

@NgModule({

})
export class AppModule {
	constructor(ngRedux: NgRedux, someEpics: SomeEpics) {
		let epics = combineEpics(
			someEpics.epicOne,
			someEpics.epicTwo
		);
		let epicMiddleware = createEpicMidleware();

		ngRedux.configureStore(reducer,[epicMiddleware]);
		epicMiddleware.run(epics);

		// or

		let epicOne = createMiddleware(someEpics.epicOne);
		let epicTwo = createMiddleware(someEpics.epicTwo);

		ngRedux.configureStore(reducer,[epicOne, epicTwo]);
	}
}

This decorator is intended to make it easier to mark which properties / methods in a class are Epics to simplify creating the epic middleware for your application.

import { Epic } from 'redux-observable-decorator';

@Injectable()
export class SomeEpics {
	@Epic() epicOne = (action$) => action$.ofType('PING').pipe(mapTo({type: 'PONG'}));
	@Epic() epicTwo = (action$) => action$.ofType('ACTION_IN').pipe(mapTo({type: 'ACTION_OUT'}));
}
import { combineDecoratedEpics } from 'redux-observable-decorator';
import { createEpicMiddleware } from 'redux-observable';

@NgModule({

})
export class AppModule {
	constructor(ngRedux:NgRedux, someEpics:SomeEpics) {
		let epics = combineDecoratedEpics(someEpics);
		const epicMiddleware = createEpicMiddleware();

		ngRedux.configureStore(reducer,[epicMiddleware]);
		epicMiddleware.run(epics);
	}
}

This can be used with vanilla redux also - as seen in the unit tests...

class Test {
	@Epic() epic = (action$) => action$.ofType('TEST_IN').pipe(mapTo({ type: 'TEST_OUT' }));
}

const reducer = (state = [], action) => state.concat(action);
const epics = new Test();
const epicMiddleware = createEpicMiddleware(epics);
const store = createStore(reducer, applyMiddleware(epicMiddleware));
epicMiddleware.run(combineDecoratedEpics(epics));

Inspiration

The @Effect decorator from ngrx/effects

Todo

  • Better docs
  • Publish on NPM
  • Improve tests
  • Get test coverage working
  • Some Anglar 2 / integration tests
  • Example App
  • Strategy for lazy loading epics (to support code-splitting)?