diff --git a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/components/stock-market-container.component.spec.ts b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/components/stock-market-container.component.spec.ts index 29dc1c076..27a6d320e 100755 --- a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/components/stock-market-container.component.spec.ts +++ b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/components/stock-market-container.component.spec.ts @@ -11,7 +11,7 @@ import { SharedModule } from '../../../../shared/shared.module'; import { State } from '../../examples.state'; import { StockMarketService } from '../stock-market.service'; -import { ActionStockMarketRetrieve } from '../stock-market.actions'; +import { actionStockMarketRetrieve } from '../stock-market.actions'; import { StockMarketContainerComponent } from './stock-market-container.component'; import { StockMarketState } from '../stock-market.model'; @@ -85,7 +85,7 @@ describe('StockMarketContainerComponent', () => { it('should trigger dispatch with correct input', () => { expect(dispatchSpy).toHaveBeenCalledTimes(1); expect(dispatchSpy).toHaveBeenCalledWith( - new ActionStockMarketRetrieve({ symbol: 'A' }) + actionStockMarketRetrieve({ symbol: 'A' }) ); expect(true).toBeTruthy(); }); diff --git a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/components/stock-market-container.component.ts b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/components/stock-market-container.component.ts index 6559c10b4..a10d5e6ec 100755 --- a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/components/stock-market-container.component.ts +++ b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/components/stock-market-container.component.ts @@ -6,7 +6,7 @@ import { take } from 'rxjs/operators'; import { ROUTE_ANIMATIONS_ELEMENTS } from '../../../../core/core.module'; import { selectStockMarket } from '../stock-market.selectors'; -import { ActionStockMarketRetrieve } from '../stock-market.actions'; +import { actionStockMarketRetrieve } from '../stock-market.actions'; import { StockMarketState } from '../stock-market.model'; import { State } from '../../examples.state'; @@ -30,6 +30,6 @@ export class StockMarketContainerComponent implements OnInit { } onSymbolChange(symbol: string) { - this.store.dispatch(new ActionStockMarketRetrieve({ symbol })); + this.store.dispatch(actionStockMarketRetrieve({ symbol })); } } diff --git a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.actions.ts b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.actions.ts index 9bcbdd3be..518b71808 100755 --- a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.actions.ts +++ b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.actions.ts @@ -1,4 +1,4 @@ -import { Action } from '@ngrx/store'; +import { createAction, props } from '@ngrx/store'; import { HttpErrorResponse } from '@angular/common/http'; import { Stock } from './stock-market.model'; @@ -9,25 +9,17 @@ export enum StockMarketActionTypes { RETRIEVE_ERROR = '[Stock] Retrieve Error' } -export class ActionStockMarketRetrieve implements Action { - readonly type = StockMarketActionTypes.RETRIEVE; +export const actionStockMarketRetrieve = createAction( + StockMarketActionTypes.RETRIEVE, + props<{ symbol: string }>() +); - constructor(readonly payload: { symbol: string }) {} -} - -export class ActionStockMarketRetrieveSuccess implements Action { - readonly type = StockMarketActionTypes.RETRIEVE_SUCCESS; - - constructor(readonly payload: { stock: Stock }) {} -} - -export class ActionStockMarketRetrieveError implements Action { - readonly type = StockMarketActionTypes.RETRIEVE_ERROR; - - constructor(readonly payload: { error: HttpErrorResponse }) {} -} +export const actionStockMarketRetrieveSuccess = createAction( + StockMarketActionTypes.RETRIEVE_SUCCESS, + props<{ stock: Stock }>() +); -export type StockMarketActions = - | ActionStockMarketRetrieve - | ActionStockMarketRetrieveSuccess - | ActionStockMarketRetrieveError; +export const actionStockMarketRetrieveError = createAction( + StockMarketActionTypes.RETRIEVE_ERROR, + props<{ error: HttpErrorResponse }>() +); diff --git a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.effects.spec.ts b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.effects.spec.ts index 0b2f34eea..f67b06567 100755 --- a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.effects.spec.ts +++ b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.effects.spec.ts @@ -6,9 +6,9 @@ import { TestScheduler } from 'rxjs/testing'; import { LocalStorageService } from '../../../core/core.module'; import { - ActionStockMarketRetrieve, - ActionStockMarketRetrieveError, - ActionStockMarketRetrieveSuccess + actionStockMarketRetrieve, + actionStockMarketRetrieveError, + actionStockMarketRetrieveSuccess } from './stock-market.actions'; import { StockMarketEffects, STOCK_MARKET_KEY } from './stock-market.effects'; import { Stock } from './stock-market.model'; @@ -32,13 +32,13 @@ describe('StockMarketEffects', () => { it('should emit ActionStockMarketRetrieveSuccess on success', done => { scheduler.run(helpers => { const { cold, expectObservable } = helpers; - const retrieveAction1 = new ActionStockMarketRetrieve({ + const retrieveAction1 = actionStockMarketRetrieve({ symbol }); - const retrieveAction2 = new ActionStockMarketRetrieve({ + const retrieveAction2 = actionStockMarketRetrieve({ symbol }); - const retrieveAction3 = new ActionStockMarketRetrieve({ + const retrieveAction3 = actionStockMarketRetrieve({ symbol }); const stock: Stock = { @@ -51,7 +51,7 @@ describe('StockMarketEffects', () => { changeNegative: false, changePercent: '2.00' }; - const successAction = new ActionStockMarketRetrieveSuccess({ + const successAction = actionStockMarketRetrieveSuccess({ stock }); const values = { @@ -72,11 +72,10 @@ describe('StockMarketEffects', () => { stockMarket ); - expectObservable( - effects.retrieveStock({ - debounce: 2 - }) - ).toBe(expected, values); + expectObservable(effects.retrieveStock({ debounce: 2 })).toBe( + expected, + values + ); setTimeout(() => { expect(localStorage.setItem).toHaveBeenCalledTimes(3); @@ -91,11 +90,11 @@ describe('StockMarketEffects', () => { it('should emit ActionStockMarketRetrieveError on error', () => { scheduler.run(helpers => { const { cold, expectObservable } = helpers; - const retrieveAction = new ActionStockMarketRetrieve({ + const retrieveAction = actionStockMarketRetrieve({ symbol }); const error = 'ERROR'; - const errorAction = new ActionStockMarketRetrieveError({ + const errorAction = actionStockMarketRetrieveError({ error } as any); const values = { @@ -114,11 +113,10 @@ describe('StockMarketEffects', () => { stockMarket ); - expectObservable( - effects.retrieveStock({ - debounce: 0 - }) - ).toBe(expected, values); + expectObservable(effects.retrieveStock({ debounce: 0 })).toBe( + expected, + values + ); }); }); }); diff --git a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.effects.ts b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.effects.ts index 46da497fa..5aec8977d 100755 --- a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.effects.ts +++ b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.effects.ts @@ -1,16 +1,14 @@ import { Injectable } from '@angular/core'; -import { Actions, Effect, ofType } from '@ngrx/effects'; -import { Action } from '@ngrx/store'; -import { asyncScheduler, of } from 'rxjs'; +import { Actions, createEffect, ofType } from '@ngrx/effects'; +import { of } from 'rxjs'; import { catchError, debounceTime, map, switchMap, tap } from 'rxjs/operators'; import { LocalStorageService } from '../../../core/core.module'; import { - ActionStockMarketRetrieve, - ActionStockMarketRetrieveError, - ActionStockMarketRetrieveSuccess, - StockMarketActionTypes + actionStockMarketRetrieve, + actionStockMarketRetrieveError, + actionStockMarketRetrieveSuccess } from './stock-market.actions'; import { StockMarketService } from './stock-market.service'; @@ -19,26 +17,26 @@ export const STOCK_MARKET_KEY = 'EXAMPLES.STOCKS'; @Injectable() export class StockMarketEffects { constructor( - private actions$: Actions, + private actions$: Actions, private localStorageService: LocalStorageService, private service: StockMarketService ) {} - @Effect() - retrieveStock = ({ debounce = 500 } = {}) => + retrieveStock = createEffect(() => ({ debounce = 500 } = {}) => this.actions$.pipe( - ofType(StockMarketActionTypes.RETRIEVE), + ofType(actionStockMarketRetrieve), tap(action => this.localStorageService.setItem(STOCK_MARKET_KEY, { - symbol: action.payload.symbol + symbol: action.symbol }) ), debounceTime(debounce), - switchMap((action: ActionStockMarketRetrieve) => - this.service.retrieveStock(action.payload.symbol).pipe( - map(stock => new ActionStockMarketRetrieveSuccess({ stock })), - catchError(error => of(new ActionStockMarketRetrieveError({ error }))) + switchMap(action => + this.service.retrieveStock(action.symbol).pipe( + map(stock => actionStockMarketRetrieveSuccess({ stock })), + catchError(error => of(actionStockMarketRetrieveError({ error }))) ) ) - ); + ) + ); } diff --git a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.reducer.spec.ts b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.reducer.spec.ts index a91625c95..f4b9f74e5 100755 --- a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.reducer.spec.ts +++ b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.reducer.spec.ts @@ -2,10 +2,9 @@ import { Stock, StockMarketState } from './stock-market.model'; import { HttpErrorResponse } from '@angular/common/http'; import { stockMarketReducer, initialState } from './stock-market.reducer'; import { - StockMarketActions, - ActionStockMarketRetrieve, - ActionStockMarketRetrieveError, - ActionStockMarketRetrieveSuccess + actionStockMarketRetrieve, + actionStockMarketRetrieveError, + actionStockMarketRetrieveSuccess } from './stock-market.actions'; const originalState: StockMarketState = { @@ -27,7 +26,7 @@ describe('StockMarketReducer', () => { describe('undefined action', () => { describe('with undefined original state', () => { it('should return the initial state', () => { - const action = {} as StockMarketActions; + const action = {} as any; const state = stockMarketReducer(undefined, action); expect(state).toBe(initialState); @@ -36,7 +35,7 @@ describe('StockMarketReducer', () => { describe('with a valid original state', () => { it('should return the original state', () => { - const action = {} as StockMarketActions; + const action = {} as any; const state = stockMarketReducer(originalState, action); expect(state).toBe(originalState); @@ -46,20 +45,20 @@ describe('StockMarketReducer', () => { describe('RETRIEVE action', () => { it('should reflect that it has started loading the provided symbol', () => { - const action = new ActionStockMarketRetrieve({ symbol: 'AEONS' }); + const action = actionStockMarketRetrieve({ symbol: 'AEONS' }); const state = stockMarketReducer(originalState, action); expect(state.loading).toBeTruthy(); expect(state.stock).toBeNull(); expect(state.error).toBeNull(); - expect(state.symbol).toBe(action.payload.symbol); + expect(state.symbol).toBe(action.symbol); }); }); describe('RETRIEVE_ERROR action', () => { it('should reflect the Error that occured', () => { const error = new HttpErrorResponse({}); - const action = new ActionStockMarketRetrieveError({ error: error }); + const action = actionStockMarketRetrieveError({ error: error }); const state = stockMarketReducer(originalState, action); expect(state.symbol).toBe(state.symbol); @@ -81,7 +80,7 @@ describe('StockMarketReducer', () => { changeNegative: false, changePercent: '+5%' }; - const action = new ActionStockMarketRetrieveSuccess({ stock: stock }); + const action = actionStockMarketRetrieveSuccess({ stock: stock }); const state = stockMarketReducer(originalState, action); expect(state.loading).toBeFalsy(); diff --git a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.reducer.ts b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.reducer.ts index c6b710637..30b294cc8 100755 --- a/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.reducer.ts +++ b/projects/angular-ngrx-material-starter/src/app/features/examples/stock-market/stock-market.reducer.ts @@ -1,45 +1,42 @@ import { StockMarketState } from './stock-market.model'; import { - StockMarketActions, - StockMarketActionTypes + actionStockMarketRetrieve, + actionStockMarketRetrieveError, + actionStockMarketRetrieveSuccess } from './stock-market.actions'; +import { Action, createReducer, on } from '@ngrx/store'; export const initialState: StockMarketState = { symbol: 'GOOGL', loading: false }; -export function stockMarketReducer( - state: StockMarketState = initialState, - action: StockMarketActions -): StockMarketState { - switch (action.type) { - case StockMarketActionTypes.RETRIEVE: - return { - ...state, - loading: true, - stock: null, - error: null, - symbol: action.payload.symbol - }; - - case StockMarketActionTypes.RETRIEVE_SUCCESS: - return { - ...state, - loading: false, - stock: action.payload.stock, - error: null - }; +const reducer = createReducer( + initialState, + on(actionStockMarketRetrieve, (state, { symbol }) => ({ + ...state, + loading: true, + stock: null, + error: null, + symbol + })), + on(actionStockMarketRetrieveSuccess, (state, { stock }) => ({ + ...state, + loading: false, + stock, + error: null + })), + on(actionStockMarketRetrieveError, (state, { error }) => ({ + ...state, + loading: false, + stock: null, + error + })) +); - case StockMarketActionTypes.RETRIEVE_ERROR: - return { - ...state, - loading: false, - stock: null, - error: action.payload.error - }; - - default: - return state; - } +export function stockMarketReducer( + state: StockMarketState | undefined, + action: Action +) { + return reducer(state, action); }