We have a Customer Portal application with TicketList and TicketDetails view components. Each component uses the HttpClient to load appropriate ticket data and store that data directly into the component.
This is poor design since these components:
- do not share the data...
- always reload the data [since routing creates new instances of the views]...
- contain business logic to load the data
Let's use NgRx to store the data in a *Tickets NgRx state layer. This lab (and the subsequent 6 other labs) will show developers how to use NgRx features and the beneficial impacts of NgRx on view components.
We already did some NgRx setup for you...
- The Customer Portal application already has its
apps/customer-portal/src/app/app.module.ts
configured with NgRx - A TicketsState feature library
libs/tickets-state
with NgRx has also been created with initial actions, reducer, and selectors; but this feature has not yet been registered with the NgRx store.
Take a moment to explore those files to quickly familiarize yourself with the NgRx artifacts and setup.
In this lab, you will:
- Use a LoadTicketsDone actions to store REST ticket data in the NgRx store
- Use a tickets reducer to process the LoadTicketsDone action
- Use tickets selectors to build queries (into the NgRx state) for future ticket push-data
- Use
StoreModule.forFeature()
to register the Tickets feature with theticketsReducer
and FEATURE_TICKETS.
- Inject the
store: Store<PartialAppState>
in the constructor - In
ngOnInit()
, useticketsQuery.getAllTickets
withstore.pipe(select())
to get a list of all available tickets and then use the router param ticketid
to extract the ticket. - When the
service.ticketById(id)
returns the ticket, save that ticket to the NgRx state usingLoadTicketDone()
The
tickets.reducer.ts
already handles theLoadTicketDone
action... so no more work is needed here.
- Inject the
store: Store<PartialAppState>
in the constructor - In constructor, use the HttpClient
ticketService.getTickets()
to load the tickets and then save the ticket data to the NgRx state by dispatching anew LoadTicketsDone()
action. - Prepare the
tickets$ : Observable<Ticket[]>
property usingthis.store.pipe(select())
instead of the HttpClient service.
Do not use imports that by-pass the library public api. E.g.
import { LoadTicketsDone } from '@tuskdesk-suite/tickets-state/src/...'
- Add
case TicketActionTypes.LOAD_ALL_TICKETS_DONE:
to process the LoadTicketsDone action and update the state.
This improvement assumes that the NgRx TicketsState will contain the desired ticket
for the ticket-details view. In what scenarios will this not work? Also, what would happen if you forgot to update the tickets.reducer.ts
to process the LoadTicketsDone
action?
Be prepared to discuss these issues and possible workarounds.
- Open the Customer Portal application with the browser: http://localhost:4203
- Confirm the Node Server is running with browser page: http://localhost:3000/api/tickets
Run the following command(s) in individual terminals:
yarn server
yarn customer-portal -- -o
If you already have one(s) running and need to restart, you can stop the run with
ctrl+c
.
Go to NgRx Lab #2: Composed Store Selectors