Setting it up

We start by downloading the entity library. To do this, we need to run the following command:

npm install @ngrx/entity

We then need to perform the following steps:

  1. Create a model.
  2. Create an entity state based on the model.
  3. Create an entity adapter.
  4. Create the initial state.
  5. Create the reducer and set up the state in the StoreModule. 

Let's start off by creating our model:

// user.model.ts

export interface User {
id: number;
name: string;
}

The preceding code is just a simple model with fields   id   and   name.  We then create our entity state, like so:

// excerpt from app.module.ts

import {
EntityState,
createEntityAdapter,
EntityAdapter
}
from "@ngrx/entity";

export interface State extends EntityState<User> {
selectedUserId: number | null;
}

This will be the return type our reducer needs to abide by. Type EntityState looks like the following, if you peek into the NgRx source code:

// from NGRX source code

export interface EntityState<T> {
ids: string[] | number[];
entities:
Dictionary<T>;
}

By extending the preceding interface EntityState, when we create type State we will also get the properties ids and entities. We will see later in this section how these properties are populated, once we start using the utility methods the entity library gives us.

The next step is to create our adapter. An instance of the adapter sits on a range of methods, allowing us to write a great deal less code. We create the adapter with the following code:

// excerpt from app.module.ts

import {
EntityState,
createEntityAdapter,
EntityAdapter
}
from "@ngrx/entity";

const userAdapter: EntityAdapter<User> = createEntityAdapter<User>();

At this point, we are almost ready; we just need to get the initial state from the adapter and provide that to our reducer.

To get the initial state, we need to talk to our adapter, like so:

// excerpt from app.module.ts

const initialState: State = {
ids: [],
entities: {},
selectedUserId: null
};

const initial = userAdapter.getInitialState(initialState);

What's happening here is that we need to create an object representing the initial state. It needs to be of type State and therefore it needs to have the properties ids, entities, and selectedUserId defined. Then, we call getInitialState() on the adapter to produce our initial state. So, what do we need the initial state for? We'll need to set it as the default value of our reducer's state. 

Next, we create our reducer and set its default state to our initial state instance, created previously:

// interfaces.ts

import { Action } from "@ngrx/store";

export interface ActionPayload<T> extends Action {
payload: T;
}

// excerpt from app.module.ts

function userReducer(state = initial, action: ActionPayload<User>): State {
switch (action.type) {
case "ADD_USER":
return userAdapter.addOne(action.payload, state);
default:
return state;
}
}
}

Note here how we call our userAdapter and invoke the method addOne(); this means that we don't have to write code that looks like this:

// example of what a reducer could look like that is NOT using @ngrx/entity

function reducer(state = [], action: ActionPayload<User>) {
switch (action.type) {
case "ADD_USER":
return [
...state.users
Object.assign({}, action.payload)
];

default:
return state;
}
}
}

The last step to setting everything up is to add the state to the StoreModule so that NgRx knows about it:

// excerpt from app.module.ts

@NgModule({
declarations: [AppComponent, EditUserComponent],
imports: [
BrowserModule,
FormsModule,
StoreModule.forRoot({
users: userReducer
})
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}

That concludes the required setup. The next steps we want to take in the following sections are how to display the data in a component, and also how to perform a full CRUD and thereby leveraging more of what the EntityAdapter has to offer.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.19.162