Suggested Videos
Part 56 - Angular route loading indicator | Text | Slides
Part 57 - Angular canactivate guard example | Text | Slides
Part 58 - Passing data between components in angular | Text | Slides
In this video we will discuss editing and updating data in Angular. To set the expectations right, we will be updating data on the client side. We will discuss persisting the data to a database table in our upcoming videos when we implement the server side service.
We are going to modify "Create Employee Form" so it supports both
Changes in Root Module file (app.module.ts) : Change the path in the following route from "create" to "edit/:id"
Changes in create-employee.component.html : The value attribute of email and phone radio buttons is set to Email and Phone respectively to match with the employee data. Otherwise when we select to edit an existing employee, his saved contact preference value will not be bound to the correct radio button. The change is bolded and italicized.
The required attribute value is updated to include capital E in Email for the validation to work correctly.
The required attribute value is updated to include capital P in Phone for the validation to work correctly.
The value attribute of male and female radio buttons is set to Male and Female respectively to match with the employee data. Otherwise when we select to edit an existing employee, his saved gender value will not be bound to the correct radio button. The change is bolded and italicized.
Notice, I have included ngIf to show the "Image Preview" button and the image, only if there is a value in the photoPath field. This avoids unnecessary 404 errors in the browser console.
Changes in create-employee.component.ts : Change ngOnInit() and saveEmployee() employee methods as shown below. Also please do not forget to include the following panelTitle property.
Changes in employee.service.ts : Change save() method as shown below
Changes in display-employee.component.html : Bind editEmployee() method to the click event of the "Edit" button
Changes in display-employee.component.ts : Include the following editEmployee() method
Changes in app.component.html : Change the "Create" menu item to point to our new route "edit/0".
Next Video : Delete operation in Angular
Part 56 - Angular route loading indicator | Text | Slides
Part 57 - Angular canactivate guard example | Text | Slides
Part 58 - Passing data between components in angular | Text | Slides
In this video we will discuss editing and updating data in Angular. To set the expectations right, we will be updating data on the client side. We will discuss persisting the data to a database table in our upcoming videos when we implement the server side service.
We are going to modify "Create Employee Form" so it supports both
- Creating a new employee
- Editing and updating an existing employee
Changes in Root Module file (app.module.ts) : Change the path in the following route from "create" to "edit/:id"
Existing Route
{
path: 'create',
component: CreateEmployeeComponent,
canDeactivate: [CreateEmployeeCanDeactivateGuardService]
}
Updated Route to support both creating a new employee and editing an existing employee. If the id route parameter value is 0, then the form will be used to create a new employee. If the id value is not 0, then the form will be used to edit an existing employee.
{
path: 'edit/:id',
component: CreateEmployeeComponent,
canDeactivate: [CreateEmployeeCanDeactivateGuardService]
}
{
path: 'create',
component: CreateEmployeeComponent,
canDeactivate: [CreateEmployeeCanDeactivateGuardService]
}
Updated Route to support both creating a new employee and editing an existing employee. If the id route parameter value is 0, then the form will be used to create a new employee. If the id value is not 0, then the form will be used to edit an existing employee.
{
path: 'edit/:id',
component: CreateEmployeeComponent,
canDeactivate: [CreateEmployeeCanDeactivateGuardService]
}
Changes in create-employee.component.html : The value attribute of email and phone radio buttons is set to Email and Phone respectively to match with the employee data. Otherwise when we select to edit an existing employee, his saved contact preference value will not be bound to the correct radio button. The change is bolded and italicized.
<div class="form-group" [class.has-error]="contactPreference.invalid
&& contactPreference.touched">
<label class="control-label">Contact Preference</label>
<div class="form-control">
<label class="radio-inline">
<input type="radio" required #contactPreference="ngModel"
name="contactPreference" value="Email"
[(ngModel)]="employee.contactPreference"> Email
</label>
<label class="radio-inline">
<input type="radio" required #contactPreference="ngModel"
name="contactPreference" value="Phone"
[(ngModel)]="employee.contactPreference"> Phone
</label>
</div>
<span class="help-block" *ngIf="contactPreference.errors?.required
&& contactPreference.touched">
Contact Preference is
required
</span>
</div>
The required attribute value is updated to include capital E in Email for the validation to work correctly.
<div class="form-group" [class.has-error]="email.invalid">
<label for="email" class="control-label">Email</label>
<input id="email" [required]="contactPreference.value=='Email'"
type="text" class="form-control" [(ngModel)]="employee.email"
#email="ngModel" name="email"
pattern="^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$">
<span class="help-block" *ngIf="email.errors?.required">
Email is required
</span>
<span class="help-block" *ngIf="email.errors?.pattern && email.touched">
Email is Invalid
</span>
</div>
The required attribute value is updated to include capital P in Phone for the validation to work correctly.
<div class="form-group" [class.has-error]="phoneNumber.invalid">
<label for="phoneNumber" class="control-label">Phone Number</label>
<input id="phoneNumber" [required]="contactPreference.value=='Phone'"
#phoneNumber="ngModel" class="form-control" type="text"
name="phoneNumber" [(ngModel)]="employee.phoneNumber">
<span class="help-block" *ngIf="phoneNumber.errors?.required">
Phone Number is required
</span>
</div>
The value attribute of male and female radio buttons is set to Male and Female respectively to match with the employee data. Otherwise when we select to edit an existing employee, his saved gender value will not be bound to the correct radio button. The change is bolded and italicized.
<div class="form-group"
[class.has-error]="gender.invalid && gender.touched">
<label class="control-label">Gender</label>
<div class="form-control">
<label class="radio-inline">
<input type="radio" name="gender" required #gender="ngModel"
value="Male" [(ngModel)]="employee.gender"> Male
</label>
<label class="radio-inline">
<input type="radio" name="gender" required #gender="ngModel"
value="Female" [(ngModel)]="employee.gender"> Female
</label>
</div>
<span class="help-block" *ngIf="gender.errors?.required && gender.touched">
Gender is required
</span>
</div>
Notice, I have included ngIf to show the "Image Preview" button and the image, only if there is a value in the photoPath field. This avoids unnecessary 404 errors in the browser console.
<div class="form-group">
<button type="button" (click)="togglePhotPreview()" class="btn btn-primary"
*ngIf="employee.photoPath !=='' && employee.photoPath !==null">
{{previewPhoto ?
"Hide " : "Show " }} Preview
</button>
</div>
<div class="form-group">
<img [src]="employee.photoPath" height="200" width="200"
*ngIf="previewPhoto &&
employee.photoPath !=='' &&
employee.photoPath !==null"/>
</div>
Changes in create-employee.component.ts : Change ngOnInit() and saveEmployee() employee methods as shown below. Also please do not forget to include the following panelTitle property.
panelTitle: string;
// Subscribe to route parameter changes and react accordingly
ngOnInit() {
this._route.paramMap.subscribe(parameterMap => {
const id = +parameterMap.get('id');
this.getEmployee(id);
});
}
saveEmployee(empForm: NgForm): void {
const newEmployee = Object.assign({}, this.employee);
this._employeeService.save(newEmployee);
empForm.reset();
this._router.navigate(['list']);
}
private getEmployee(id: number) {
// If the id is 0, we want to create a
new employee. So we intialise the employee
// property with an Employee object with all properties set to null. The template
// is bound to this employee property so all the form fields are displayed blank,
// to enter details of a new employee we want to create
// property with an Employee object with all properties set to null. The template
// is bound to this employee property so all the form fields are displayed blank,
// to enter details of a new employee we want to create
if (id === 0) {
this.employee = {
id: null,
name: null,
gender: null,
contactPreference: null,
phoneNumber: null,
email: '',
dateOfBirth: null,
department: null,
isActive: null,
photoPath: null
};
// Resetting the form, resets any
previous validation errors
this.createEmployeeForm.reset();
this.panelTitle = 'Create Employee';
} else {
// If the Id is not 0, then retrieve
the respective employee using the employee
// service. Copy the values into a new object and assign that object as the value
// for the employee property. Otherwise the employee property holds a reference
// to the employee object in the array in the EmployeeService. This means any
// changes we make on the form are automatically saved, without we explicitly
// service. Copy the values into a new object and assign that object as the value
// for the employee property. Otherwise the employee property holds a reference
// to the employee object in the array in the EmployeeService. This means any
// changes we make on the form are automatically saved, without we explicitly
// saving by clicking the Save button.
this.employee = Object.assign({}, this._employeeService.getEmployee(id));
this.panelTitle = 'Edit Employee';
}
}
Changes in employee.service.ts : Change save() method as shown below
save(employee: Employee) {
if (employee.id === null) {
// reduce() method reduces the array to
a single value. This method executes
// the provided function for each
element of the array (from left-to-right)
// When we implement the server side
service to save data to the database
// table, we do not have to compute the
id, as the server will assing it
const maxId = this.listEmployees.reduce(function (e1, e2) {
return (e1.id > e2.id) ? e1 : e2;
}).id;
employee.id = maxId + 1;
this.listEmployees.push(employee);
} else {
const foundIndex = this.listEmployees.findIndex(e => e.id === employee.id);
this.listEmployees[foundIndex] = employee;
}
}
Changes in display-employee.component.html : Bind editEmployee() method to the click event of the "Edit" button
<button class="btn btn-primary" (click)="editEmployee()">Edit</button>
Changes in display-employee.component.ts : Include the following editEmployee() method
editEmployee() {
this._router.navigate(['/edit', this.employee.id]);
}
Changes in app.component.html : Change the "Create" menu item to point to our new route "edit/0".
<li>
<a routerLink="edit/0">Create</a>
</li>
Next Video : Delete operation in Angular
No comments:
Post a Comment
It would be great if you can help share these free resources