a4-reducer
TypeScript icon, indicating that this package has built-in type declarations

8.3.0 • Public • Published

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 authStoreAuthStore) {
    this.username$ = authStore.map(p => p.username);
}
 
handleSignIn(usernamestring, passwordstring) {
    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>(arrayT[], newElementT, indexnumber)T[]

immutableRemoveElement

Returning a new array with element at index being removed.

immutableRemoveElement<T>(arrayT[], indexnumber)T[]

immutableInsertElement

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

immutableInsertElement<T>(arrayT[], elementT, indexnumber)T[]

immutablePrependElement

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

immutablePrependElement<T>(arrayT[], elementT)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[]

Package Sidebar

Install

npm i a4-reducer

Weekly Downloads

0

Version

8.3.0

License

MIT

Unpacked Size

250 kB

Total Files

41

Last publish

Collaborators

  • cccheng