Add support for error actions

This commit is contained in:
Jerko Steiner 2019-01-19 17:39:54 +01:00
parent c1d21350a8
commit c1c7c829e7
4 changed files with 32 additions and 11 deletions

View File

@ -3,14 +3,23 @@
// section: Type inference in conditional types
type Unpacked<T> = T extends Promise<infer U> ? U : T
import {IAction} from './IAction'
import {IErrorAction} from './IErrorAction'
// Also from TypeScript handbook:
// https://www.typescriptlang.org/docs/handbook/advanced-types.html
type FunctionProperties<T> = {
[K in keyof T]: T[K] extends (...args: any[]) => IAction<any, string> ? {
[K in keyof T]:
T[K] extends (...args: any[]) => IAction<any, string>
? {
payload: Unpacked<ReturnType<T[K]>['payload']>,
type: Unpacked<ReturnType<T[K]>['type']>,
}: never
}
: T[K] extends (...args: any[]) => IErrorAction<string>
? {
error: Error,
type: Unpacked<ReturnType<T[K]>['type']>,
}
: never
}
// https://stackoverflow.com/questions/48305190/

View File

@ -0,0 +1,4 @@
export interface IErrorAction<ActionType extends string> {
error: Error,
type: ActionType
}

View File

@ -1,22 +1,19 @@
import {ActionTypes} from './ActionTypes'
import {IAPIDef, ICredentials, IUser} from '@rondo/common'
import {IAction} from './IAction'
import {IErrorAction} from './IErrorAction'
import {IHTTPClient} from '../http/IHTTPClient'
export enum UserActionKeys {
USER_LOG_IN = 'USER_LOG_IN',
USER_LOG_IN_FULFILLED = 'USER_LOG_IN_FULFILLED',
USER_LOG_IN_PENDING = 'USER_LOG_IN_PENDING',
USER_LOG_IN_REJECTED = 'USER_LOG_IN_REJECTED',
USER_LOG_OUT = 'USER_LOG_OUT',
USER_LOG_OUT_FULFILLED = 'USER_LOG_OUT_FULFILLED',
USER_LOG_OUT_PENDING = 'USER_LOG_OUT_PENDING',
USER_LOG_OUT_REJECTED = 'USER_LOG_OUT_REJECTED',
}
interface IAction<PayloadType, ActionType> {
payload: Promise<PayloadType> | PayloadType,
type: ActionType
}
export class UserActions {
constructor(protected readonly http: IHTTPClient<IAPIDef>) {}
@ -27,6 +24,13 @@ export class UserActions {
}
}
logInError(error: Error): IErrorAction<UserActionKeys.USER_LOG_IN_REJECTED> {
return {
error,
type: UserActionKeys.USER_LOG_IN_REJECTED,
}
}
logOut(): IAction<unknown, UserActionKeys.USER_LOG_OUT> {
return {
payload: this.http.get('/auth/logout'),

View File

@ -2,18 +2,22 @@ import {IUser} from '@rondo/common'
import {UserActionKeys, UserActionType} from '../actions/UserActions'
interface IState {
error?: string,
user?: IUser
}
const defaultState: IState = {
error: undefined,
user: undefined,
}
export function user(state = defaultState, action: UserActionType): IState {
switch (action.type) {
case UserActionKeys.USER_LOG_IN:
return {user: action.payload}
return {...state, user: action.payload}
case UserActionKeys.USER_LOG_OUT:
return {user: undefined}
return {...state, user: undefined}
case UserActionKeys.USER_LOG_IN_REJECTED:
return {...state, error: action.error.message}
}
}