From b55f84214466e430f84bb71455ca4aa5dbf0e700 Mon Sep 17 00:00:00 2001 From: Brandon Roberts Date: Fri, 26 Apr 2019 14:16:54 -0500 Subject: [PATCH] 07-action-creators complete --- src/app/books/actions/books-api.actions.ts | 66 ++++++-------- src/app/books/actions/books-page.actions.ts | 89 ++++++++----------- src/app/books/books.effects.ts | 18 ++-- .../books-page/books-page.component.ts | 12 +-- src/app/shared/state/books.reducer.ts | 12 +-- 5 files changed, 86 insertions(+), 111 deletions(-) diff --git a/src/app/books/actions/books-api.actions.ts b/src/app/books/actions/books-api.actions.ts index 888e01d..3dfad86 100644 --- a/src/app/books/actions/books-api.actions.ts +++ b/src/app/books/actions/books-api.actions.ts @@ -1,39 +1,29 @@ import { Book } from "src/app/shared/models/book.model"; -import { Action } from "@ngrx/store"; - -export enum BooksApiActionTypes { - BooksLoaded = '[Books API] Books Loaded Success', - BookCreated = '[Books API] Book Created', - BookUpdated = '[Books API] Book Updated', - BookDeleted = '[Books API] Book Deleted', -} - -export class BooksLoaded implements Action { - readonly type = BooksApiActionTypes.BooksLoaded; - - constructor(public books: Book[]) {} -} - -export class BookCreated implements Action { - readonly type = BooksApiActionTypes.BookCreated; - - constructor(public book: Book) {} -} - -export class BookUpdated implements Action { - readonly type = BooksApiActionTypes.BookUpdated; - - constructor(public book: Book) {} -} - -export class BookDeleted implements Action { - readonly type = BooksApiActionTypes.BookDeleted; - - constructor(public book: Book) {} -} - -export type BooksApiActions = - | BooksLoaded - | BookCreated - | BookUpdated - | BookDeleted; +import { createAction, props } from "@ngrx/store"; + +export const booksLoaded = createAction( + "[Books API] Books Loaded Success", + props<{ books: Book[] }>() +); + +export const bookCreated = createAction( + "[Books API] Book Created", + props<{ book: Book }>() +); + +export const bookUpdated = createAction( + "[Books API] Book Updated", + props<{ book: Book }>() +); + +export const bookDeleted = createAction( + "[Books API] Book Deleted", + props<{ book: Book }>() +); + +export type BooksApiActions = ReturnType< + | typeof booksLoaded + | typeof bookCreated + | typeof bookUpdated + | typeof bookDeleted +>; diff --git a/src/app/books/actions/books-page.actions.ts b/src/app/books/actions/books-page.actions.ts index 289e7f4..0de5068 100644 --- a/src/app/books/actions/books-page.actions.ts +++ b/src/app/books/actions/books-page.actions.ts @@ -1,52 +1,37 @@ -import { Book } from "src/app/shared/models/book.model"; -import { Action } from "@ngrx/store"; - -export enum BooksActionTypes { - Enter = '[Books Page] Enter', - SelectBook = '[Books Page] Select Book', - ClearSelectedBook = '[Books Page] Clear Selected Book', - CreateBook = '[Books Page] Create Book', - UpdateBook = '[Books Page] Update Book', - DeleteBook = '[Books Page] Delete Book' -} - -export class Enter implements Action { - readonly type = BooksActionTypes.Enter; -} - -export class SelectBook implements Action { - readonly type = BooksActionTypes.SelectBook; - - constructor(public bookId: string) {} -} - -export class ClearSelectedBook implements Action { - readonly type = BooksActionTypes.ClearSelectedBook; -} - -export class CreateBook implements Action { - readonly type = BooksActionTypes.CreateBook; - - constructor(public book: Book) {} -} - -export class UpdateBook implements Action { - readonly type = BooksActionTypes.UpdateBook; - - constructor(public book: Book) {} -} - -export class DeleteBook implements Action { - readonly type = BooksActionTypes.DeleteBook; - - constructor(public book: Book) {} -} - -export type BooksActions = - | Enter - | SelectBook - | ClearSelectedBook - | CreateBook - | UpdateBook - | DeleteBook -; +import { createAction, props } from "@ngrx/store"; +import { BookRequiredProps, Book } from "src/app/shared/models/book.model"; + +export const enter = createAction("[Books Page] Enter"); + +export const selectBook = createAction( + "[Books Page] Select Book", + props<{ bookId: string }>() +); + +export const clearSelectedBook = createAction( + "[Books Page] Clear Selected Book" +); + +export const createBook = createAction( + "[Books Page] Create Book", + props<{ book: BookRequiredProps }>() +); + +export const updateBook = createAction( + "[Books Page] Update Book", + props<{ book: Book; changes: BookRequiredProps }>() +); + +export const deleteBook = createAction( + "[Books Page] Delete Book", + props<{ book: Book }>() +); + +export type BooksActions = ReturnType< + | typeof enter + | typeof selectBook + | typeof clearSelectedBook + | typeof createBook + | typeof updateBook + | typeof deleteBook +>; diff --git a/src/app/books/books.effects.ts b/src/app/books/books.effects.ts index 96e5ab1..5fd49d3 100644 --- a/src/app/books/books.effects.ts +++ b/src/app/books/books.effects.ts @@ -10,11 +10,11 @@ export class BooksEffects { @Effect() loadBooks$ = this.actions$.pipe( - ofType(BooksPageActions.BooksActionTypes.Enter), + ofType(BooksPageActions.enter.type), mergeMap(() => this.booksService.all() .pipe( - map(books => new BooksApiActions.BooksLoaded(books)), + map(books => BooksApiActions.booksLoaded({books})), catchError(() => EMPTY) ) ) @@ -22,11 +22,11 @@ export class BooksEffects { @Effect() createBook$ = this.actions$.pipe( - ofType(BooksPageActions.BooksActionTypes.CreateBook), + ofType(BooksPageActions.createBook.type), mergeMap(action => this.booksService.create(action.book) .pipe( - map(book => new BooksApiActions.BookCreated(book)), + map(book => BooksApiActions.bookCreated({book})), catchError(() => EMPTY) ) ) @@ -34,11 +34,11 @@ export class BooksEffects { @Effect() updateBook$ = this.actions$.pipe( - ofType(BooksPageActions.BooksActionTypes.UpdateBook), + ofType(BooksPageActions.updateBook.type), mergeMap(action => this.booksService.update(action.book.id, action.book) .pipe( - map(book => new BooksApiActions.BookUpdated(book)), + map(book => BooksApiActions.bookUpdated({book})), catchError(() => EMPTY) ) ) @@ -46,15 +46,15 @@ export class BooksEffects { @Effect() deleteBook$ = this.actions$.pipe( - ofType(BooksPageActions.BooksActionTypes.DeleteBook), + ofType(BooksPageActions.deleteBook.type), mergeMap(action => this.booksService.delete(action.book.id) .pipe( - map(() => new BooksApiActions.BookDeleted(action.book)), + map(() => BooksApiActions.bookDeleted({ book: action.book})), catchError(() => EMPTY) ) ) ); - constructor(private booksService: BooksService, private actions$: Actions) {} + constructor(private booksService: BooksService, private actions$: Actions) {} } \ No newline at end of file diff --git a/src/app/books/components/books-page/books-page.component.ts b/src/app/books/components/books-page/books-page.component.ts index 416cbdb..1b3fbfe 100755 --- a/src/app/books/components/books-page/books-page.component.ts +++ b/src/app/books/components/books-page/books-page.component.ts @@ -31,11 +31,11 @@ export class BooksPageComponent implements OnInit { } getBooks() { - this.store.dispatch(new BooksPageActions.Enter()); + this.store.dispatch(BooksPageActions.enter()); } onSelect(book: Book) { - this.store.dispatch(new BooksPageActions.SelectBook(book.id)); + this.store.dispatch(BooksPageActions.selectBook({bookId: book.id})); } onCancel() { @@ -43,7 +43,7 @@ export class BooksPageComponent implements OnInit { } removeSelectedBook() { - this.store.dispatch(new BooksPageActions.ClearSelectedBook()); + this.store.dispatch(BooksPageActions.clearSelectedBook()); } onSave(book: Book) { @@ -55,14 +55,14 @@ export class BooksPageComponent implements OnInit { } saveBook(book: Book) { - this.store.dispatch(new BooksPageActions.CreateBook(book)); + this.store.dispatch(BooksPageActions.createBook({book})); } updateBook(book: Book) { - this.store.dispatch(new BooksPageActions.UpdateBook(book)); + this.store.dispatch(BooksPageActions.updateBook({book, changes: book})); } onDelete(book: Book) { - this.store.dispatch(new BooksPageActions.DeleteBook(book)); + this.store.dispatch(BooksPageActions.deleteBook({book})); } } diff --git a/src/app/shared/state/books.reducer.ts b/src/app/shared/state/books.reducer.ts index dd707a7..78e773a 100644 --- a/src/app/shared/state/books.reducer.ts +++ b/src/app/shared/state/books.reducer.ts @@ -36,28 +36,28 @@ export const initialState = adapter.getInitialState({ export function reducer(state = initialState, action: BooksPageActions.BooksActions | BooksApiActions.BooksApiActions): State { switch(action.type) { - case BooksApiActions.BooksApiActionTypes.BooksLoaded: + case BooksApiActions.booksLoaded.type: return adapter.addAll(action.books, state); - case BooksPageActions.BooksActionTypes.SelectBook: + case BooksPageActions.selectBook.type: return { ...state, activeBookId: action.bookId }; - case BooksPageActions.BooksActionTypes.ClearSelectedBook: + case BooksPageActions.clearSelectedBook.type: return { ...state, activeBookId: null }; - case BooksApiActions.BooksApiActionTypes.BookCreated: + case BooksApiActions.bookCreated.type: return adapter.addOne(action.book, {...state, activeBookId: action.book.id}); - case BooksApiActions.BooksApiActionTypes.BookUpdated: + case BooksApiActions.bookUpdated.type: return adapter.updateOne({id: action.book.id, changes: action.book}, {...state, activeBookId: action.book.id}); - case BooksApiActions.BooksApiActionTypes.BookDeleted: + case BooksApiActions.bookDeleted.type: return adapter.removeOne(action.book.id, {...state, activeBookId: null}); default: