@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.

  1. Use the CLI to generate a new PassengersModule with the boilerplate for @ngrx/entity. For this, switch into the folder flight-app\src\app and use the following commands:

    ng g module passengers
    ng g @ngrx/schematics:entity passengers/+state/passenger --module ../passengers.module.ts --creators
    
  2. Discover the generated files.

  3. Open the file passenger.model and add a name property to the Passenger class. Also, make the id a number:

    export interface Passenger {
        id: number;    // <-- Modify (number)
        name: string;  // <-- Add this
    }
    
  4. In the passengers folder, create a new file passenger.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);
    
  5. Remove the Selectors from passenger.reducer.ts.

  6. Create an index.ts barrel file to allow direct import from the +store folder in your component:

    export * from './passenger.model';
    export * from './passenger.reducer';
    export * from './passenger.actions';
    export * from './passenger.selectors';
    
  7. In the passengers folder, create a new PassengersComponent. In its ngOnInit method, send an AddPassengers action with an hard coded array of passengers to the store and query all the passengers using the above mentioned selectAllPassengers selector. 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>
    

  8. Make sure, the PassengersComponent is declared AND exported with the PassengerModule.

  9. Make sure, the PassengersModule is imported into the AppModule.

  10. Call the PassengersComponent within the HomeComponent to try it out.

    <app-passengers></app-passengers>
    
  11. 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.