This project was generated with Angular CLI version 1.7.4.
- Install
jasmine-marbles
- Write a hot marble/observable that will emulate a stream of actions
- Write a cold marble/observable that will emulate the behaviour of the effect
- Compare them using
expect(...).toBeObservable(...)
- Use the effect from Ex2 to pass
collection
from router store toShelfService.getData
- Adjust
ShelfService.getData
to filter out books depending on the collection (optional argument) - Hide shelves in
BooksShelfComponent
based on the value ofmode$
(collection). - Remove data filtering data logic from
BooksShelfComponent
- Add an Effect to your effects class, that will start fetching books when
ROUTER_NAVIGATION
action appears - Write selectors that will help you get
store.router.state.params.collection
that tells which shelf is selected. - Use these selectors to set
mode$
inBooksShelfComponent
- Go to your reducer and clear items in the initial state,
- Go to
books-shelf.component.html
and hidediv.collection_container
when books are not loaded with*ngIf
- Add there a notification that books are loading
- Install
@ngrx/router-store
package - Extend
NgrxModuleState
to have router key of typeRouterReducerState<RouterStateUrl>
- theRouterStateUrl
was implemented for you instore/router-store.ts
- Import and register
routerReducer
in your presentActionReducerMap
(suggested key:router
) - Wire up
StoreRouterConnectingModule.forRoot({ stateKey: 'router' })
with your module - Add
{ provide: RouterStateSerializer, useClass: CustomSerializer }
to your module providers.CustomSerializer
is implemented instore/router-store.ts
.
- Install
@ngrx/store-devtools
- Install in your web browser the Redux Devtools Extension
- Wire-up
StoreDevToolsModule.instrument({ maxAge: 25 })
with your module
- Implement adding a new book:
** Create
AddBook
action ** Handle the action in the reducer ** Dispatch the action inBooksShelfComponent
in appropriate handler
- Remove unused methods from
ShelfService
- Add
ShelfService.fetchBooks
method that will return books with some delay, to emulate the HTTP request behaviour (maybe usetimer
fromrxjs
) - Be sure that
ShelfService
returns other titles than in the default state - Install
@ngrx/effects
package - Add
LoadBooks
andBooksLoaded
actions, handle them in the reducer (addloading: boolean
state) - Write an effect that reloads books on
LoadBooks
action and emitsBooksLoaded
action - Register the effect with
EffectsModule.forRoot
- Add a button that will dispatch
LoadBooks
action
- Implement
UpdateBook
action that will be dispatched when e.g. moving a book - Handle updating a book in the reducer:
- Notice that there's no invariant property, so introduce
id
- Assign unique id to a
NgrxBook
, useuuid
package - Handle an update action that carries an
id
- Notice that there's no invariant property, so introduce
- Test the reducer (think of it as comparing state after passing an action with expected state)
- Dispatch the update action on book move (
BookShelfComponent
)
- Refactor
BooksShelfComponent
to use| async
instead of subscribing tobooks$
- Extract books selection logic to
store/selectors.ts
, usecreateSelector
function, - Write a unit test for your reducer
- Inject
Store<NgrxModuleState>
to theBooksShelfComponent
- Use the store to render books in
BooksShelfComponent
:- Stop using the service in
getData
- Fetch all books from the store using
select
operator, - Temporarily subscribe to the store and assign them to the existing
books
field - Map the book collection to a filtered one, based on
this.mode
(if set)
- Stop using the service in
Since we're not relying on internal component state anymore, adding books won't work for a while.
- Install
@ngrx/store
package - Write your first reducer, HINT:
(State, Action) => State
- Add initial, default state to your reducer
- Wire up the reducer with the module using
StoreModule.forRoot
method andActionReducerMap