8.3.0 • Published 5 years ago

a4-reducer v8.3.0

Weekly downloads
-
License
MIT
Repository
-
Last release
5 years ago

a4-reducer

Install

npm install a4-reducer

How to setup actions

auth-action.ts

import { Action } from 'a4-reducer';

export interface AuthState {
    username: string;
    error: any;
    busy: boolean;
}

export enum Types {
    request_sign_in = 'auth.signin.request',
    sign_in_succeed = 'auth.signin.succeed',
    sign_in_failed = 'auth.signin.fail',
    sign_in_reset = 'auth.signin.reset',
    request_sign_out = 'auth.signout.request',
    sign_out_succeed = 'auth.signout.succeed',
}

interface SignInRequestPayload {
    username: string;
    password: string;
};

export class SignInRequest implements Action<SignInRequestPayload> {
    readonly type = Types.request_sign_in;
    constructor(public payload: SignInRequestPayload) { }
}

interface Token {
    token: string;
    expiresIn: number;
}

export interface GetOAuthResponse {
    lastName: string;
    tokenType: string;
    token: Token;
}

export interface SignInSucceddPayload extends GetOAuthResponse {
    redirect: boolean;
}

export class SignInSucceed implements Action<SignInSucceddPayload> {
    readonly type = Types.sign_in_succeed;
    constructor(public payload: SignInSucceddPayload) { }
}

export class SignInFail implements Action<void>{
    readonly type = Types.sign_in_failed;
    readonly payload = null;
}

export class SignInReset implements Action<void> {
    readonly type = Types.sign_in_reset;
    readonly payload = null;
}

export class SignOutRequest implements Action<void> {
    readonly type = Types.request_sign_out;
    readonly payload = null;
}

export class SignOutSucceed implements Action<void> {
    readonly type = Types.sign_out_succeed;
    readonly payload = null;
}

export type Actions = SignInRequest
    | SignInSucceed
    | SignInFail
    | SignInReset
    | SignOutSucceed;

How to setup a store

auth-store.ts

import { Reducer, Effect, Store, Action, InitialState } from 'a4-reducer';
import { AuthState, Types, SignInSucceed, SignInFail,
  SignInRequest, SignInSucceddPayload, Actions, SignOutSucceed
} from './auth-action';
import { HttpClient } from '@angular/common/http';
import { Router } from '@angular/router';

@InitialState({
  auth: {
    username: null,
    error: null,
    busy: false
  }
})
@Injectable({
  providedIn: 'root'
})
export class AuthStore extends Store<AuthState> {

    constructor(private http: HttpClient, private router: Router) {
        super();
    }

    @Reducer()
    reducer(state: Store1State, action: Actions) {
        switch (action.type) {
            case Types.sign_in_reset:
                return { ...state, error: null, busy: false };

            case Types.request_sign_in:
                return { ...state, busy: true };

            case Types.sign_in_succeed:
                return { ...state, username: action.payload.lastName };

            case Types.sign_in_failed:
                return { ...state, error: action.payload, busy: false };

            case Types.sign_out_succeed:
                return { ...state, username: null };
        }
    }

    @Effect(Types.request_sign_in)
    async requestSignIn(action: SignInRequest) {
        try {
            const result = (await this.http.post<SignInSucceddPayload>('/v1/oauth', action.payload).toPromise());
            return new SignInSucceed(result);
        } catch (e) {
            return new SignInFail(e);
        }
    }

    @Effect(Types.sign_in_succeed)
    signInSucceed(action: SignInSucceed) {
        document.cookie = `TOKEN=${action.payload.token.token};path=/`;

        if (action.payload.redirect === undefined)
        this.router.navigate(['/tos']);
    }

    @Effect(Types.request_sign_out)
    requestSignOut(action: Action<void>) {
        document.cookie = `TOKEN=;path=/;expires=Thu, 01 Jan 1970 00:00:00 GMT`;
        return new SignOutSucceed();
    }

    @Effect(Types.sign_out_succeed)
    signOutSucceed(action: Action<void>) {
        this.router.navigate(['/signin']);
    }
}

How to use the store in your app

import { AuthStore } from './auth-store';
import { requestSignIn } from './auth-action';

private username$: Observable<string>;

constructor(private authStore: AuthStore) {
    this.username$ = authStore.map(p => p.username);
}

handleSignIn(username: string, password: string) {
    this.authStore.dispatch(new requestSignIn({
        username,
        password
    }));
}

To enable console log

import { enableConsoleLog } from 'a4-reducer';

if (!environment.production) {
    enableConsoleLog();
}

Difference between .map and .select

Select will only fire the subscription when the current alue is different than the last while Map will fire the subscription when there is a new value set in the store.

How to add side effect without using decorator

import { addSideEffect, removeSideEffect } from 'a4-reducer';

boundHandleThisAction = this.handleThisAction.bind(this);

ngOnInit() {
    addSideEffect('ACTION.NAME', this.boundHandleThisAction);
}

ngOnDestroy() {
    removeSideEffect('ACTION.NAME', this.boundHandleThisAction);
}

Immutable Methods (protected)

These immutable methods can only be used within the store class.

immutableReplaceElement

Returning a new array with element at index being replaced by newElement.

immutableReplaceElement<T>(array: T[], newElement: T, index: number): T[]

immutableRemoveElement

Returning a new array with element at index being removed.

immutableRemoveElement<T>(array: T[], index: number): T[]

immutableInsertElement

Returning a new array with element being inserted at specified index.

immutableInsertElement<T>(array: T[], element: T, index: number): T[]

immutablePrependElement

Returning a new array with element inserted at the start (first element) of the given array.

immutablePrependElement<T>(array: T[], element: T): T[]

immutableAppendElement

Returning a new array with element inserted at the end (last element) of the given array.

immutableAppendElement<T>(array: T[], element: T): T[]
8.3.0

5 years ago

8.2.2

5 years ago

8.2.1

5 years ago

8.2.0

5 years ago

8.1.0

5 years ago

8.0.0

5 years ago