Updating users

There are two things we need to do to support updating users:

  • Add a component that supports updating
  • Adding a CASE to our reducer that listens to an action and calls the appropriate adapter method

Let's start with our component:

// edit-user.component.ts

import {
Component,
OnInit,
Output,
Input,
EventEmitter
}
from "@angular/core";

@Component({
selector: "edit-user",
template: `
<div>
<input [(ngModel)]="user.name" />
<button (click)="save.emit(user)" >Save</button>
</div>
`
})
export class EditUserComponent implements OnInit {
private _user;

@Input()
get user() {
return this._user;
}


set user(val) {
this._user = Object.assign({}, val);
}


@Output() save = new EventEmitter();

constructor() {}
ngOnInit() {}
}

Here, we have a component that takes a user as input and is able to invoke a save as output thereby calling the parent component. In short, this component allows us to edit a user.

Now we need to add this component to app.module.ts so that other components within this module can use it:

// excerpt from app.module.ts

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

Now we are ready to add the component to the parent components template, like so:

// app.component.ts - adding EditUserComponent to the markup

import { Component } from "@angular/core";
import { AppState } from "./app-state";
import { Store } from "@ngrx/store";
import { map } from "rxjs/operators";

@Component({
selector: "app-root",
template: `
<div style="border: solid 1px black; padding: 10px;"
*ngFor="let user of users$ | async">
{{ user.name }}
<edit-user [user]="user" (save)="update($event)" ></edit-user>
</div>
<div>
<input [(ngModel)]="user" /> <button (click)="add()">Add</button>
</div>
`
})
export class AppComponent {
title = "app";
users$;
user;
id = 1;

constructor(private store: Store<AppState>) {
this.users$ = this.store
.select(state => state.users.entities)
.pipe(map(this.toArray));
this.users$.subscribe(data => console.log("users", data));
}

toArray(obj) {
const keys = Object.keys(obj);
return keys.map(key => obj[key]);
}

add() {
const newUser = { id: this.id++, name: this.user };
this.store.dispatch({
type: "ADD_USER",
payload: newUser
});
}

update(user) {
console.log("updating", user);
this.store.dispatch({ type: "UPDATE_USER", payload: user });
}

}

This code shows us how we add the EditUserComponent to the markup, as well as us adding the update() method that, when invoked, dispatches the action UPDATE_USER. This will lead to our reducer being invoked which leads us to our final piece of the puzzle, the required changes we need to make to the reducer:

// 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);
case "UPDATE_USER":
return userAdapter.updateOne({

id: action.payload.id,
changes: action.payload
},
state
);
default:
return state;
}
}

We now support the ability to update our users list.

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

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