From c007649f374bc3253feb3b2e9b2465cce52e4453 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 20 Feb 2019 10:32:54 +0000 Subject: [PATCH 1/2] feat(Store): add action creator --- modules/store/spec/action_creator.spec.ts | 122 ++++++++++++++++++++++ modules/store/src/action_creator.ts | 39 +++++++ modules/store/src/index.ts | 1 + modules/store/src/models.ts | 11 +- modules/store/src/selector.ts | 4 +- 5 files changed, 171 insertions(+), 6 deletions(-) create mode 100644 modules/store/spec/action_creator.spec.ts create mode 100644 modules/store/src/action_creator.ts diff --git a/modules/store/spec/action_creator.spec.ts b/modules/store/spec/action_creator.spec.ts new file mode 100644 index 0000000000..ae7e88c72a --- /dev/null +++ b/modules/store/spec/action_creator.spec.ts @@ -0,0 +1,122 @@ +import { ActionsUnion, createAction } from '@ngrx/store'; + +describe('createAction with properties', () => { + describe('action type: const', () => { + it('type only', () => { + const ACTION1 = '[action] Action1 blah'; + const actualAction = createAction(ACTION1); + type expectedActionType = Readonly<{ + type: '[action] Action1 blah'; + }>; + + const expectedAction: expectedActionType = { + type: ACTION1, + }; + expect(actualAction).toEqual(expectedAction); + }); + + it('type and properties', () => { + const properties = { userName: 'UserName', age: 32 }; + const ACTION1 = '[action] Action1 blah'; + const actualAction = createAction(ACTION1, properties); + type expectedActionType = Readonly<{ + type: '[action] Action1 blah'; + userName: string; + age: number; + }>; + + const expectedAction: expectedActionType = { + type: ACTION1, + userName: properties.userName, + age: properties.age, + }; + expect(actualAction).toEqual(expectedAction); + }); + }); + + describe('action type: enum', () => { + it('type only', () => { + enum ActionTypes { + Action1 = '[action] Action1 blah', + Action2 = '[action] Action2 blah', + } + + const actualAction = createAction(ActionTypes.Action1); + type expectedActionType = Readonly<{ + type: ActionTypes.Action1; + }>; + + const expectedAction: expectedActionType = { + type: ActionTypes.Action1, + }; + expect(actualAction).toEqual(expectedAction); + }); + + it('type and properties', () => { + const properties = { userName: 'UserName', age: 32 }; + enum ActionTypes { + Action1 = '[action] Action1 blah', + Action2 = '[action] Action2 blah', + } + + const actualAction = createAction(ActionTypes.Action1, properties); + type expectedActionType = Readonly<{ + type: ActionTypes.Action1; + userName: string; + age: number; + }>; + + const expectedAction: expectedActionType = { + type: ActionTypes.Action1, + userName: properties.userName, + age: properties.age, + }; + expect(actualAction).toEqual(expectedAction); + }); + }); +}); + +describe('ActionsUnion type', () => { + enum ActionTypes { + Login = '[Login Page] Login', + Logout = '[Login Page] Logout', + } + + const Actions = { + login: (userName: string, password: string) => + createAction(ActionTypes.Login, { userName, password }), + logout: () => createAction(ActionTypes.Logout), + }; + + type Actions = ActionsUnion; + + it('Action with properties', () => { + const properties = { userName: 'UserName', password: 'Password' }; + const actualAction = Actions.login( + properties.userName, + properties.password + ); + type expectedActionType = Readonly<{ + type: ActionTypes.Login; + userName: string; + password: string; + }>; + const expectedAction: expectedActionType = { + type: ActionTypes.Login, + userName: properties.userName, + password: properties.password, + }; + expect(actualAction).toEqual(expectedAction); + }); + + it('Action without properties', () => { + const actualAction = Actions.logout(); + type expectedActionType = Readonly<{ + type: ActionTypes.Logout; + }>; + const expectedAction: expectedActionType = { + type: ActionTypes.Logout, + }; + expect(actualAction).toEqual(expectedAction); + }); +}); diff --git a/modules/store/src/action_creator.ts b/modules/store/src/action_creator.ts new file mode 100644 index 0000000000..5bf768a9b7 --- /dev/null +++ b/modules/store/src/action_creator.ts @@ -0,0 +1,39 @@ +// ========== +// = Adapted from: rex-tils +// = https://github.com/Hotell/rex-tils +// ========== + +import { Action, AnyFn } from './models'; + +export function createAction(type: T): Action; +export function createAction< + T extends string, + P extends { + [key: string]: any; + } +>(type: T, props: P): Action; +export function createAction< + T extends string, + P extends { + [key: string]: any; + } +>(type: T, props?: P) { + /* + The following line requires Typescript 3.2: Generic spread expressions in + object literals. + https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html + + Typescript 3.1.1 gives error: Spread types may only be created from + object types. ts(2698) + */ + // const action = payload === undefined ?{ type } : { type, ...payload }; + const action = + props === undefined ? { type } : { type, ...(props as object) }; + return action; +} + +/** + * Simple alias to save keystrokes when defining JS typed object maps + */ +type StringMap = { [key: string]: T }; +export type ActionsUnion> = ReturnType; diff --git a/modules/store/src/index.ts b/modules/store/src/index.ts index ce02914c93..7824029400 100644 --- a/modules/store/src/index.ts +++ b/modules/store/src/index.ts @@ -52,3 +52,4 @@ export { _createStoreReducers, _createFeatureReducers, } from './store_module'; +export { ActionsUnion, createAction } from './action_creator'; diff --git a/modules/store/src/models.ts b/modules/store/src/models.ts index 34413a0139..d556511848 100644 --- a/modules/store/src/models.ts +++ b/modules/store/src/models.ts @@ -1,6 +1,11 @@ -export interface Action { - type: string; -} +export type Action = P extends void + ? Readonly<{ type: T }> + : Readonly<{ + type: T; + }> & + Readonly

; + +export type AnyFn = (...args: any[]) => any; export type TypeId = () => T; diff --git a/modules/store/src/selector.ts b/modules/store/src/selector.ts index 332d3d01d0..df6b872cd3 100644 --- a/modules/store/src/selector.ts +++ b/modules/store/src/selector.ts @@ -1,6 +1,4 @@ -import { Selector, SelectorWithProps } from './models'; - -export type AnyFn = (...args: any[]) => any; +import { AnyFn, Selector, SelectorWithProps } from './models'; export type MemoizedProjection = { memoized: AnyFn; reset: () => void }; From ee0d10201a494aa95422c95ea0bab65c11cb3d4a Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 21 Feb 2019 11:14:58 +0000 Subject: [PATCH 2/2] refactor(Example): use action creators --- .../src/app/auth/actions/auth-api.actions.ts | 26 +++++++------------ .../src/app/auth/actions/auth.actions.ts | 24 ++++++----------- .../example-app/src/app/auth/actions/index.ts | 15 ++++++++--- .../app/auth/actions/login-page.actions.ts | 13 +++++----- .../containers/login-page.component.spec.ts | 2 +- .../auth/containers/login-page.component.ts | 2 +- .../src/app/auth/effects/auth.effects.spec.ts | 26 +++++++++---------- .../src/app/auth/effects/auth.effects.ts | 26 +++++++++---------- .../app/auth/reducers/auth.reducer.spec.ts | 4 +-- .../src/app/auth/reducers/auth.reducer.ts | 15 +++++++---- .../src/app/auth/reducers/index.ts | 5 +--- .../auth/reducers/login-page.reducer.spec.ts | 6 ++--- .../app/auth/reducers/login-page.reducer.ts | 19 ++++++++------ .../app/auth/services/auth-guard.service.ts | 2 +- .../src/app/core/containers/app.component.ts | 4 +-- 15 files changed, 91 insertions(+), 98 deletions(-) diff --git a/projects/example-app/src/app/auth/actions/auth-api.actions.ts b/projects/example-app/src/app/auth/actions/auth-api.actions.ts index 48c19b3696..bc2e84608c 100644 --- a/projects/example-app/src/app/auth/actions/auth-api.actions.ts +++ b/projects/example-app/src/app/auth/actions/auth-api.actions.ts @@ -1,4 +1,4 @@ -import { Action } from '@ngrx/store'; +import { ActionsUnion, createAction } from '@ngrx/store'; import { User } from '@example-app/auth/models/user'; export enum AuthApiActionTypes { @@ -7,20 +7,12 @@ export enum AuthApiActionTypes { LoginRedirect = '[Auth/API] Login Redirect', } -export class LoginSuccess implements Action { - readonly type = AuthApiActionTypes.LoginSuccess; +export const AuthApiActions = { + loginRedirect: () => createAction(AuthApiActionTypes.LoginRedirect), + loginSuccess: (user: User) => + createAction(AuthApiActionTypes.LoginSuccess, { user }), + loginFailure: (error: any) => + createAction(AuthApiActionTypes.LoginFailure, { error }), +}; - constructor(public payload: { user: User }) {} -} - -export class LoginFailure implements Action { - readonly type = AuthApiActionTypes.LoginFailure; - - constructor(public payload: { error: any }) {} -} - -export class LoginRedirect implements Action { - readonly type = AuthApiActionTypes.LoginRedirect; -} - -export type AuthApiActionsUnion = LoginSuccess | LoginFailure | LoginRedirect; +export type AuthApiActions = ActionsUnion; diff --git a/projects/example-app/src/app/auth/actions/auth.actions.ts b/projects/example-app/src/app/auth/actions/auth.actions.ts index 5151d08f34..914f0792b8 100644 --- a/projects/example-app/src/app/auth/actions/auth.actions.ts +++ b/projects/example-app/src/app/auth/actions/auth.actions.ts @@ -1,4 +1,4 @@ -import { Action } from '@ngrx/store'; +import { Action, ActionsUnion, createAction } from '@ngrx/store'; export enum AuthActionTypes { Logout = '[Auth] Logout', @@ -6,19 +6,11 @@ export enum AuthActionTypes { LogoutConfirmationDismiss = '[Auth] Logout Confirmation Dismiss', } -export class Logout implements Action { - readonly type = AuthActionTypes.Logout; -} - -export class LogoutConfirmation implements Action { - readonly type = AuthActionTypes.LogoutConfirmation; -} - -export class LogoutConfirmationDismiss implements Action { - readonly type = AuthActionTypes.LogoutConfirmationDismiss; -} +export const AuthActions = { + logout: () => createAction(AuthActionTypes.Logout), + logoutConfirmation: () => createAction(AuthActionTypes.LogoutConfirmation), + logoutConfirmationDismiss: () => + createAction(AuthActionTypes.LogoutConfirmationDismiss), +}; -export type AuthActionsUnion = - | Logout - | LogoutConfirmation - | LogoutConfirmationDismiss; +export type AuthActions = ActionsUnion; diff --git a/projects/example-app/src/app/auth/actions/index.ts b/projects/example-app/src/app/auth/actions/index.ts index f7e4df41be..ab01e7a0b3 100644 --- a/projects/example-app/src/app/auth/actions/index.ts +++ b/projects/example-app/src/app/auth/actions/index.ts @@ -1,5 +1,12 @@ -import * as AuthActions from './auth.actions'; -import * as AuthApiActions from './auth-api.actions'; -import * as LoginPageActions from './login-page.actions'; +import { AuthActions, AuthActionTypes } from './auth.actions'; +import { AuthApiActions, AuthApiActionTypes } from './auth-api.actions'; +import { LoginPageActions, LoginPageActionTypes } from './login-page.actions'; -export { AuthActions, AuthApiActions, LoginPageActions }; +export { + AuthActions, + AuthActionTypes, + AuthApiActions, + AuthApiActionTypes, + LoginPageActions, + LoginPageActionTypes, +}; diff --git a/projects/example-app/src/app/auth/actions/login-page.actions.ts b/projects/example-app/src/app/auth/actions/login-page.actions.ts index 2a70296d7a..882c905ef7 100644 --- a/projects/example-app/src/app/auth/actions/login-page.actions.ts +++ b/projects/example-app/src/app/auth/actions/login-page.actions.ts @@ -1,14 +1,13 @@ -import { Action } from '@ngrx/store'; +import { ActionsUnion, createAction } from '@ngrx/store'; import { Credentials } from '@example-app/auth/models/user'; export enum LoginPageActionTypes { Login = '[Login Page] Login', } -export class Login implements Action { - readonly type = LoginPageActionTypes.Login; +export const LoginPageActions = { + login: (credentials: Credentials) => + createAction(LoginPageActionTypes.Login, { credentials }), +}; - constructor(public payload: { credentials: Credentials }) {} -} - -export type LoginPageActionsUnion = Login; +export type LoginPageActions = ActionsUnion; diff --git a/projects/example-app/src/app/auth/containers/login-page.component.spec.ts b/projects/example-app/src/app/auth/containers/login-page.component.spec.ts index 9da3433266..6cc3c78f92 100644 --- a/projects/example-app/src/app/auth/containers/login-page.component.spec.ts +++ b/projects/example-app/src/app/auth/containers/login-page.component.spec.ts @@ -57,7 +57,7 @@ describe('Login Page', () => { it('should dispatch a login event on submit', () => { const credentials: any = {}; - const action = new LoginPageActions.Login({ credentials }); + const action = LoginPageActions.login(credentials); instance.onSubmit(credentials); diff --git a/projects/example-app/src/app/auth/containers/login-page.component.ts b/projects/example-app/src/app/auth/containers/login-page.component.ts index f56a2577f6..9792a554c4 100644 --- a/projects/example-app/src/app/auth/containers/login-page.component.ts +++ b/projects/example-app/src/app/auth/containers/login-page.component.ts @@ -24,6 +24,6 @@ export class LoginPageComponent implements OnInit { ngOnInit() {} onSubmit(credentials: Credentials) { - this.store.dispatch(new LoginPageActions.Login({ credentials })); + this.store.dispatch(LoginPageActions.login(credentials)); } } diff --git a/projects/example-app/src/app/auth/effects/auth.effects.spec.ts b/projects/example-app/src/app/auth/effects/auth.effects.spec.ts index 55dd1bb1f4..94c8447e77 100644 --- a/projects/example-app/src/app/auth/effects/auth.effects.spec.ts +++ b/projects/example-app/src/app/auth/effects/auth.effects.spec.ts @@ -57,8 +57,8 @@ describe('AuthEffects', () => { it('should return an auth.LoginSuccess action, with user information if login succeeds', () => { const credentials: Credentials = { username: 'test', password: '' }; const user = { name: 'User' } as User; - const action = new LoginPageActions.Login({ credentials }); - const completion = new AuthApiActions.LoginSuccess({ user }); + const action = LoginPageActions.login(credentials); + const completion = AuthApiActions.loginSuccess(user); actions$ = hot('-a---', { a: action }); const response = cold('-a|', { a: user }); @@ -70,10 +70,10 @@ describe('AuthEffects', () => { it('should return a new auth.LoginFailure if the login service throws', () => { const credentials: Credentials = { username: 'someOne', password: '' }; - const action = new LoginPageActions.Login({ credentials }); - const completion = new AuthApiActions.LoginFailure({ - error: 'Invalid username or password', - }); + const action = LoginPageActions.login(credentials); + const completion = AuthApiActions.loginFailure( + 'Invalid username or password' + ); const error = 'Invalid username or password'; actions$ = hot('-a---', { a: action }); @@ -88,7 +88,7 @@ describe('AuthEffects', () => { describe('loginSuccess$', () => { it('should dispatch a RouterNavigation action', (done: any) => { const user = { name: 'User' } as User; - const action = new AuthApiActions.LoginSuccess({ user }); + const action = AuthApiActions.loginSuccess(user); actions$ = of(action); @@ -101,7 +101,7 @@ describe('AuthEffects', () => { describe('loginRedirect$', () => { it('should dispatch a RouterNavigation action when auth.LoginRedirect is dispatched', (done: any) => { - const action = new AuthApiActions.LoginRedirect(); + const action = AuthApiActions.loginRedirect(); actions$ = of(action); @@ -112,7 +112,7 @@ describe('AuthEffects', () => { }); it('should dispatch a RouterNavigation action when auth.Logout is dispatched', (done: any) => { - const action = new AuthActions.Logout(); + const action = AuthActions.logout(); actions$ = of(action); @@ -125,8 +125,8 @@ describe('AuthEffects', () => { describe('logoutConfirmation$', () => { it('should dispatch a Logout action if dialog closes with true result', () => { - const action = new AuthActions.LogoutConfirmation(); - const completion = new AuthActions.Logout(); + const action = AuthActions.logoutConfirmation(); + const completion = AuthActions.logout(); actions$ = hot('-a', { a: action }); const expected = cold('-b', { b: completion }); @@ -139,8 +139,8 @@ describe('AuthEffects', () => { }); it('should dispatch a LogoutConfirmationDismiss action if dialog closes with falsy result', () => { - const action = new AuthActions.LogoutConfirmation(); - const completion = new AuthActions.LogoutConfirmationDismiss(); + const action = AuthActions.logoutConfirmation(); + const completion = AuthActions.logoutConfirmationDismiss(); actions$ = hot('-a', { a: action }); const expected = cold('-b', { b: completion }); diff --git a/projects/example-app/src/app/auth/effects/auth.effects.ts b/projects/example-app/src/app/auth/effects/auth.effects.ts index 7db06fe730..47d7a0042f 100644 --- a/projects/example-app/src/app/auth/effects/auth.effects.ts +++ b/projects/example-app/src/app/auth/effects/auth.effects.ts @@ -7,7 +7,10 @@ import { catchError, exhaustMap, map, tap } from 'rxjs/operators'; import { LoginPageActions, AuthActions, + AuthActionTypes, AuthApiActions, + AuthApiActionTypes, + LoginPageActionTypes, } from '@example-app/auth/actions'; import { Credentials } from '@example-app/auth/models/user'; import { AuthService } from '@example-app/auth/services/auth.service'; @@ -17,28 +20,25 @@ import { LogoutConfirmationDialogComponent } from '@example-app/auth/components/ export class AuthEffects { @Effect() login$ = this.actions$.pipe( - ofType(LoginPageActions.LoginPageActionTypes.Login), - map(action => action.payload.credentials), + ofType(LoginPageActionTypes.Login), + map(action => action.credentials), exhaustMap((auth: Credentials) => this.authService.login(auth).pipe( - map(user => new AuthApiActions.LoginSuccess({ user })), - catchError(error => of(new AuthApiActions.LoginFailure({ error }))) + map(AuthApiActions.loginSuccess), + catchError(error => of(AuthApiActions.loginFailure(error))) ) ) ); @Effect({ dispatch: false }) loginSuccess$ = this.actions$.pipe( - ofType(AuthApiActions.AuthApiActionTypes.LoginSuccess), + ofType(AuthApiActionTypes.LoginSuccess), tap(() => this.router.navigate(['/'])) ); @Effect({ dispatch: false }) loginRedirect$ = this.actions$.pipe( - ofType( - AuthApiActions.AuthApiActionTypes.LoginRedirect, - AuthActions.AuthActionTypes.Logout - ), + ofType(AuthApiActionTypes.LoginRedirect, AuthActionTypes.Logout), tap(authed => { this.router.navigate(['/login']); }) @@ -46,7 +46,7 @@ export class AuthEffects { @Effect() logoutConfirmation$ = this.actions$.pipe( - ofType(AuthActions.AuthActionTypes.LogoutConfirmation), + ofType(AuthActionTypes.LogoutConfirmation), exhaustMap(() => { const dialogRef = this.dialog.open< LogoutConfirmationDialogComponent, @@ -58,14 +58,12 @@ export class AuthEffects { }), map( result => - result - ? new AuthActions.Logout() - : new AuthActions.LogoutConfirmationDismiss() + result ? AuthActions.logout() : AuthActions.logoutConfirmationDismiss() ) ); constructor( - private actions$: Actions, + private actions$: Actions, private authService: AuthService, private router: Router, private dialog: MatDialog diff --git a/projects/example-app/src/app/auth/reducers/auth.reducer.spec.ts b/projects/example-app/src/app/auth/reducers/auth.reducer.spec.ts index 6b9b9846c7..06fa965720 100644 --- a/projects/example-app/src/app/auth/reducers/auth.reducer.spec.ts +++ b/projects/example-app/src/app/auth/reducers/auth.reducer.spec.ts @@ -25,7 +25,7 @@ describe('AuthReducer', () => { describe('LOGIN_SUCCESS', () => { it('should add a user set loggedIn to true in auth state', () => { const user = { name: 'test' } as User; - const createAction = new AuthApiActions.LoginSuccess({ user }); + const createAction = AuthApiActions.loginSuccess(user); const expectedResult = { user: { name: 'test' }, @@ -42,7 +42,7 @@ describe('AuthReducer', () => { const initialState = { user: { name: 'test' }, } as fromAuth.State; - const createAction = new AuthActions.Logout(); + const createAction = AuthActions.logout(); const expectedResult = fromAuth.initialState; diff --git a/projects/example-app/src/app/auth/reducers/auth.reducer.ts b/projects/example-app/src/app/auth/reducers/auth.reducer.ts index 797ab9f0af..cb0a6153b9 100644 --- a/projects/example-app/src/app/auth/reducers/auth.reducer.ts +++ b/projects/example-app/src/app/auth/reducers/auth.reducer.ts @@ -1,4 +1,9 @@ -import { AuthApiActions, AuthActions } from '@example-app/auth/actions'; +import { + AuthActions, + AuthActionTypes, + AuthApiActions, + AuthApiActionTypes, +} from '@example-app/auth/actions'; import { User } from '@example-app/auth/models/user'; export interface State { @@ -11,17 +16,17 @@ export const initialState: State = { export function reducer( state = initialState, - action: AuthApiActions.AuthApiActionsUnion | AuthActions.AuthActionsUnion + action: AuthApiActions | AuthActions ): State { switch (action.type) { - case AuthApiActions.AuthApiActionTypes.LoginSuccess: { + case AuthApiActionTypes.LoginSuccess: { return { ...state, - user: action.payload.user, + user: action.user, }; } - case AuthActions.AuthActionTypes.Logout: { + case AuthActionTypes.Logout: { return initialState; } diff --git a/projects/example-app/src/app/auth/reducers/index.ts b/projects/example-app/src/app/auth/reducers/index.ts index 29c31aaeec..c569246317 100644 --- a/projects/example-app/src/app/auth/reducers/index.ts +++ b/projects/example-app/src/app/auth/reducers/index.ts @@ -17,10 +17,7 @@ export interface State extends fromRoot.State { auth: AuthState; } -export const reducers: ActionReducerMap< - AuthState, - AuthApiActions.AuthApiActionsUnion -> = { +export const reducers: ActionReducerMap = { status: fromAuth.reducer, loginPage: fromLoginPage.reducer, }; diff --git a/projects/example-app/src/app/auth/reducers/login-page.reducer.spec.ts b/projects/example-app/src/app/auth/reducers/login-page.reducer.spec.ts index c81149bbcc..2af1a1a1ae 100644 --- a/projects/example-app/src/app/auth/reducers/login-page.reducer.spec.ts +++ b/projects/example-app/src/app/auth/reducers/login-page.reducer.spec.ts @@ -19,7 +19,7 @@ describe('LoginPageReducer', () => { describe('LOGIN', () => { it('should make pending to true', () => { const user = { username: 'test' } as Credentials; - const createAction = new LoginPageActions.Login({ credentials: user }); + const createAction = LoginPageActions.login(user); const expectedResult = { error: null, @@ -35,7 +35,7 @@ describe('LoginPageReducer', () => { describe('LOGIN_SUCCESS', () => { it('should have no error and no pending state', () => { const user = { name: 'test' } as User; - const createAction = new AuthApiActions.LoginSuccess({ user }); + const createAction = AuthApiActions.loginSuccess(user); const expectedResult = { error: null, @@ -51,7 +51,7 @@ describe('LoginPageReducer', () => { describe('LOGIN_FAILURE', () => { it('should have an error and no pending state', () => { const error = 'login failed'; - const createAction = new AuthApiActions.LoginFailure({ error }); + const createAction = AuthApiActions.loginFailure(error); const expectedResult = { error: error, diff --git a/projects/example-app/src/app/auth/reducers/login-page.reducer.ts b/projects/example-app/src/app/auth/reducers/login-page.reducer.ts index 8e84ab37f7..19a734f0f2 100644 --- a/projects/example-app/src/app/auth/reducers/login-page.reducer.ts +++ b/projects/example-app/src/app/auth/reducers/login-page.reducer.ts @@ -1,4 +1,9 @@ -import { AuthApiActions, LoginPageActions } from '@example-app/auth/actions'; +import { + AuthApiActions, + AuthApiActionTypes, + LoginPageActions, + LoginPageActionTypes, +} from '@example-app/auth/actions'; export interface State { error: string | null; @@ -12,12 +17,10 @@ export const initialState: State = { export function reducer( state = initialState, - action: - | AuthApiActions.AuthApiActionsUnion - | LoginPageActions.LoginPageActionsUnion + action: AuthApiActions | LoginPageActions ): State { switch (action.type) { - case LoginPageActions.LoginPageActionTypes.Login: { + case LoginPageActionTypes.Login: { return { ...state, error: null, @@ -25,7 +28,7 @@ export function reducer( }; } - case AuthApiActions.AuthApiActionTypes.LoginSuccess: { + case AuthApiActionTypes.LoginSuccess: { return { ...state, error: null, @@ -33,10 +36,10 @@ export function reducer( }; } - case AuthApiActions.AuthApiActionTypes.LoginFailure: { + case AuthApiActionTypes.LoginFailure: { return { ...state, - error: action.payload.error, + error: action.error, pending: false, }; } diff --git a/projects/example-app/src/app/auth/services/auth-guard.service.ts b/projects/example-app/src/app/auth/services/auth-guard.service.ts index c0402b1670..0537d667bd 100644 --- a/projects/example-app/src/app/auth/services/auth-guard.service.ts +++ b/projects/example-app/src/app/auth/services/auth-guard.service.ts @@ -17,7 +17,7 @@ export class AuthGuard implements CanActivate { select(fromAuth.getLoggedIn), map(authed => { if (!authed) { - this.store.dispatch(new AuthApiActions.LoginRedirect()); + this.store.dispatch(AuthApiActions.loginRedirect()); return false; } diff --git a/projects/example-app/src/app/core/containers/app.component.ts b/projects/example-app/src/app/core/containers/app.component.ts index 81bc56b81e..eb6dcc4a25 100644 --- a/projects/example-app/src/app/core/containers/app.component.ts +++ b/projects/example-app/src/app/core/containers/app.component.ts @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { select, Store } from '@ngrx/store'; import { Observable } from 'rxjs'; -import * as AuthActions from '@example-app/auth/actions/auth.actions'; +import { AuthActions } from '@example-app/auth/actions'; import * as fromAuth from '@example-app/auth/reducers'; import * as fromRoot from '@example-app/reducers'; import { LayoutActions } from '@example-app/core/actions'; @@ -64,6 +64,6 @@ export class AppComponent { logout() { this.closeSidenav(); - this.store.dispatch(new AuthActions.LogoutConfirmation()); + this.store.dispatch(AuthActions.logoutConfirmation()); } }