@ngrx/entity and @ngrx/schematics
Managing Passengers
In this exercise, you will leverage @ngrx/entity and @ngrx/schematics to manage Passenger entities with the store. For this, you will create an separate PassengerModule with a PassengerComponent.
-
Use the CLI to generate a new
PassengersModulewith the boilerplate for@ngrx/entity. For this, switch into the folderflight-app\src\appand use the following commands:ng g module passengers ng g @ngrx/schematics:entity passengers/+state/passenger --module ../passengers.module.ts --creators -
Discover the generated files.
-
Open the file
passenger.modeland add anameproperty to thePassengerclass. Also, make the id a number:export interface Passenger { id: number; // <-- Modify (number) name: string; // <-- Add this } -
In the
passengersfolder, create a new filepassenger.selectors.ts:import * as fromPassenger from './passenger.reducer'; import { createFeatureSelector } from '@ngrx/store'; import { passengersFeatureKey } from './passenger.reducer'; // Selector pointing to passenger state in store export const selectPassengerState = createFeatureSelector<fromPassenger.State>(passengersFeatureKey); // Generic selectors for the entity passenger export const { selectIds, selectEntities, selectAll, selectTotal, } = fromPassenger.adapter.getSelectors(selectPassengerState); -
Remove the Selectors from
passenger.reducer.ts. -
Create an
index.tsbarrel file to allow direct import from the+storefolder in your component:export * from './passenger.model'; export * from './passenger.reducer'; export * from './passenger.actions'; export * from './passenger.selectors'; -
In the
passengersfolder, create a newPassengersComponent. In itsngOnInitmethod, send anAddPassengersaction with an hard coded array of passengers to the store and query all the passengers using the above mentionedselectAllPassengersselector. Display the passengers in the template.Show code (TypeScript)
import { Component, OnInit } from '@angular/core'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import * as fromPassenger from './+state'; @Component({ selector: 'app-passengers', templateUrl: './passengers.component.html', styleUrls: ['./passengers.component.css'] }) export class PassengersComponent implements OnInit { passengers$: Observable<fromPassenger.Passenger[]> = this.store.select(fromPassenger.selectAll); constructor(private store: Store) { } ngOnInit() { this.store.dispatch(fromPassenger.addPassengers({ passengers: [ { id: 1, name: 'Max' }, { id: 2, name: 'Susi' } ]})); } }Show code (HTML)
<div class="card"> <div class="header"> <h2 class="title">Latest Passengers</h2> </div> <div class="content"> <pre>{{ passengers$ | async | json}}</pre> </div> </div> -
Make sure, the
PassengersComponentis declared AND exported with thePassengerModule. -
Make sure, the
PassengersModuleis imported into theAppModule. -
Call the
PassengersComponentwithin theHomeComponentto try it out.<app-passengers></app-passengers> -
Test your application.
Bonus: Loading passengers **
Extend your solution to load passengers using a search form and an effect. You can use the following Web API for this:
http://angular.at/api/passenger?name=Muster
Please note that this Web API is using PascalCase to display attributes with XML but camelCase for JSON to respect the respective usual conventions.