0.1.37 • Published 7 years ago

ngrx-store-simplr v0.1.37

Weekly downloads
4
License
MIT
Repository
github
Last release
7 years ago

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


Usage

Declare the app state interfaces.

// app/store/models/index.ts

export interface AppState {
  counter: number;
}

Create reducer and initialState to import into app.module.ts.

// app/store/reducer.ts

import { combineReducers } from '@ngrx/store';
import { Wrapper } from 'ngrx-store-simplr';
import { AppState } from './models';

const wrapper = new Wrapper<AppState>();

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.

// app/app.module.ts

import { 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.

// app/services/counter.ts

import { Simplr } from 'ngrx-store-simplr';
import { AppState } from '../store/models';
import { initialState } from '../store/reducer';

@Injectable()
export class CounterService {
  constructor(
    private simplr: Simplr<AppState>,
  ) { }

  increment() {
    this.simplr.dispatch('counter', (state) => state + 1);
  }

  reset() {
    this.simplr.dispatch('counter', initialState.counter);
  }
}

Create a component to call service functions.

// app/containers/counter.ts

import { State } from '@ngrx/store';
import { AppState } from '../store/models';
import { CounterService } from '../services/counter';

@Component({
  selector: 'app-counter-container',
  template: `
    <button (click)="increment()">increment</button>
    <button (click)="reset()">reset</button>
    <pre>{{ state$ | async | json }}</pre>
  `
})
export class CounterContainerComponent {
  constructor(
    public state$: State<AppState>,
    private service: CounterService,
  ) { }

  increment() {
    this.service.increment();
  }

  reset() {
    this.service.reset();
  }
}

Done!
Did you notice that you wrote no actions and no reducers?


Demos


Details

dispatch

dispatch function allows below sync and async writings.

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.

interface Result<T, K extends keyof T> {
  action: Action,
  state: T,
  partial: T[K],
}
// getting dispatched Action
const action: Observable<Action> = 
  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<AppState> =
  this.simplr
    .dispatch('counter', (state) => state + 1 )
    .map(result => result.state) // state ==> { counter: 1 }

// getting udpated current state under the key
const partial: Observable<number> =
  this.simplr
    .dispatch('counter', (state) => state + 1 )
    .map(result => result.partial) // partial ==> 1

dispatch function allows to set some options.

// description option
const action: Observable<Action> = 
  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<Action> = 
  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 } )
0.1.37

7 years ago

0.1.36

7 years ago

0.1.35

7 years ago

0.1.33

7 years ago

0.1.32

7 years ago

0.1.31

7 years ago

0.1.30

7 years ago

0.1.29

7 years ago

0.1.28

7 years ago

0.1.27

7 years ago

0.1.26

7 years ago

0.1.25

7 years ago

0.1.24

7 years ago

0.1.23

7 years ago

0.1.22

7 years ago

0.1.21

7 years ago

0.1.20

7 years ago

0.1.19

7 years ago

0.1.18

7 years ago

0.1.17

7 years ago

0.1.16

7 years ago

0.1.15

7 years ago

0.1.14

7 years ago

0.1.13

7 years ago

0.1.12

7 years ago

0.1.11

7 years ago

0.1.10

7 years ago

0.1.9

7 years ago

0.1.8

7 years ago

0.1.7

7 years ago

0.1.6

7 years ago

0.1.5

7 years ago

0.1.4

7 years ago

0.1.3

7 years ago

0.1.2

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago