npm.io
0.0.13 • Published 8 years ago

@ngfk/ng-store

Licence
MIT
Version
0.0.13
Deps
0
Vulns
0
Weekly
0

@ngfk/ng-store

State management powered by RxJS enforcing type safety, inspired by @ngrx/store and Redux. Creating reducers and dispatching actions will be type safe.

npm version

Setup

TLDR

  1. Define state structure
  2. Map actions
  3. Create reducers
  4. Create store

1. Define state structure

interface Todo {
    readonly id: number;
    readonly text: string;
    readonly completed: boolean;
}

enum Filter {
    All,
    Completed,
    Active
}

interface State {
    readonly todos: Todo[];
    readonly filter: Filter;
}
2. Map actions
interface TodoActionMap {
    TODO_ADD: { id: number; text: string };
    TODO_TOGGLE: number;
    TODO_REMOVE: number;
}

interface FilterActionMap {
    FILTER_SET: Filter;
}

interface ActionMap extends TodoActionMap, FilterActionMap {}
3. Create reducers
const todosReducer = createReducer<Todo[], TodoActionMap>([], {
    TODO_ADD: (state, payload) => [
        ...state,
        { id: payload.id, text: payload.text, completed: false }
    ],
    TODO_TOGGLE: (state, payload) => {
        return state.map(
            todo =>
                todo.id === payload
                    ? { ...todo, completed: !todo.completed }
                    : todo
        );
    },
    TODO_REMOVE: (state, payload) => {
        return state.filter(todo => todo.id !== payload);
    }
});

const filterReducer = createReducer<Filter, FilterActionMap>(Filter.All, {
    FILTER_SET: (_, payload) => payload
});

const reducer = combineReducers<State>({
    todos: todosReducer,
    filter: filterReducer
});
4. Create store service & provide it
import { Injectable } from '@angular/core';
import { Store } from '@ngfk/store';

import { ActionMap, reducer, State } from '../state';

@Injectable()
export class StoreService extends Store<State, ActionMap> {
    constructor() {
        super(reducer);
    }
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { NgStoreModule } from '@ngfk/ng-store';

@NgModule({
    declarations: [AppComponent],
    imports: [
        BrowserModule,
        NgStoreModule.forRoot({
            store: StoreService
        })
    ],
    providers: [],
    bootstrap: [AppComponent]
})
export class AppModule {}

Example Usage

import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';

@Component({
    selector: 'app-root',
    template: `
        <div>
            <button (click)="dispatch()">dispatch</button>
            <button (click)="clear()">clear</button>
            <hr>
            <p>State:</p>
            <pre>{{todos$ | async | json}}</pre>
        </div>
    `
})
export class AppComponent {
    public todos$: Observable<Todo[]>;

    constructor(private store: StoreService) {
        this.todos$ = this.store.select(state => state.todos);
    }

    public dispatch(): void {
        this.store.dispatch('TODO_ADD', 'Dispatched TODO!');
    }

    public clear(): void {
        this.store.reset();
    }
}

Keywords