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 ) ;
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