https://github.com/ovrmrw/ngrx-store-simplr
A wrapper library for @ngrx/store to use Redux concept in an easy way.
https://github.com/ovrmrw/ngrx-store-simplr
angular ngrx-store ngrx-store-simplr rxjs typescript
Last synced: 7 days ago
JSON representation
A wrapper library for @ngrx/store to use Redux concept in an easy way.
- Host: GitHub
- URL: https://github.com/ovrmrw/ngrx-store-simplr
- Owner: ovrmrw
- License: mit
- Created: 2017-04-21T06:15:23.000Z (about 8 years ago)
- Default Branch: master
- Last Pushed: 2017-05-09T13:58:07.000Z (almost 8 years ago)
- Last Synced: 2025-03-31T16:59:02.771Z (26 days ago)
- Topics: angular, ngrx-store, ngrx-store-simplr, rxjs, typescript
- Language: TypeScript
- Homepage:
- Size: 87.9 KB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Simplr
A wrapper library for @ngrx/store to use Redux concept in an easy way.---
Maybe your desires:
- like to use Redux.
- but writing many actions and reducers is painful.
- very painful.
- to handle async actions is so painful.
- finding an easy way to use Redux concept.
- want to use Angular and RxJS.Here Simplr comes into play.
## Install
```
$ npm install --save @ngrx/core @ngrx/store ngrx-store-simplr
```You also need to install Angular and RxJS.
---
## Examples
- [simplr-counter](https://github.com/ovrmrw/simplr-counter)
- [simplr-timestamp](https://github.com/ovrmrw/simplr-timestamp)---
## Usage
Declare the app state interfaces.
```ts
// app/store/models/index.tsexport interface AppState {
counter: number;
}
```Create `reducer` and `initialState` to import into `app.module.ts`.
```ts
// app/store/reducer.tsimport { combineReducers } from '@ngrx/store';
import { Wrapper } from 'ngrx-store-simplr';
import { AppState } from './models';const wrapper = new Wrapper();
const wrappedReducers = wrapper.mergeReducersIntoWrappedReducers({
counter: null // if you have a reducer for this key, set it here instead of null.
});const rootReducer = combineReducers(wrappedReducers);
export function reducer(state, action) { // workaround for AoT compile
return rootReducer(state, action);
}export const initialState: AppState = {
counter: 0
};
```Edit `app.module.ts` in order to use Simplr.
```ts
// app/app.module.tsimport { StoreModule } from '@ngrx/store';
import { SimplrModule } from 'ngrx-store-simplr';
import { reducer, initialState } from './store/reducer';@NgModule({
imports: [
...,
StoreModule.provideStore(reducer, initialState), // <== Add
SimplrModule.forRoot(), // <== Add
],
})
export class AppModule { }
```Create a service to dispatch to the store.
```ts
// app/services/counter.tsimport { Simplr } from 'ngrx-store-simplr';
import { AppState } from '../store/models';
import { initialState } from '../store/reducer';@Injectable()
export class CounterService {
constructor(
private simplr: Simplr,
) { }increment() {
this.simplr.dispatch('counter', (state) => state + 1);
}reset() {
this.simplr.dispatch('counter', initialState.counter);
}
}
```Create a component to call service functions.
```ts
// app/containers/counter.tsimport { State } from '@ngrx/store';
import { AppState } from '../store/models';
import { CounterService } from '../services/counter';@Component({
selector: 'app-counter-container',
template: `
increment
reset
{{ state$ | async | json }}
`
})
export class CounterContainerComponent {
constructor(
public state$: State,
private service: CounterService,
) { }increment() {
this.service.increment();
}reset() {
this.service.reset();
}
}
```Done!
Did you notice that you wrote no actions and no reducers?---
## Demos
- [simplr-counter on GitHub Pages](https://ovrmrw.github.io/simplr-counter/)
- [simplr-timestamp on GitHub Pages](https://ovrmrw.github.io/simplr-timestamp/)---
## Details
### dispatch
#### `dispatch` function allows below sync and async writings.
```ts
this.simplr.dispatch('counter', (state) => state + 1 ) // callback
// or
this.simplr.dispatch('counter', 1) // value
// or
this.simplr.dispatch('counter', Promise.resolve((state) => state + 1 )) // callback in Promise
// or
this.simplr.dispatch('counter', Promise.resolve(1)) // value in Promise
// or
this.simplr.dispatch('counter', Observable.of((state) => state + 1 )) // callback in Observable
// or
this.simplr.dispatch('counter', Observable.of(1)) // value in Observable
```#### `dispatch` function returns Observable result especially for testing.
```ts
interface Result {
action: Action,
state: T,
partial: T[K],
}
``````ts
// getting dispatched Action
const action: Observable =
this.simplr
.dispatch('counter', (state) => state + 1 )
.map(result => result.action) // action ==> { type: 'counter @UPDATE@', payload: 1 }// getting updated current whole state
const state: Observable =
this.simplr
.dispatch('counter', (state) => state + 1 )
.map(result => result.state) // state ==> { counter: 1 }// getting udpated current state under the key
const partial: Observable =
this.simplr
.dispatch('counter', (state) => state + 1 )
.map(result => result.partial) // partial ==> 1
```#### `dispatch` function allows to set some options.
```ts
// description option
const action: Observable =
this.simplr
.dispatch('counter', (state) => state + 1, { desc: 'foobar' } )
.map(result => result.action) // action ==> { type: 'counter @UPDATE@', payload: 1, desc: 'foobar' }// timeout option (default: 1000 * 15)
const action: Observable =
this.simplr
.dispatch('counter', Observable.of((state) => state + 1).delay(100), { timeout: 90 } )
.map(result => result.action) // action ==> { type: 'counter @FAILED@' }// retry option (default: 3)
this.simplr.dispatch('counter', /* will try this HTTP request 10 times */, { retry: 10 } )// logging option ... if set be true, the result will be shown on browser console.
this.simplr.dispatch('counter', (state) => state + 1, { logging: true } )
```