Update Task Form
- Create update form
Build a form component for editing existing tasks.
- Populate form data
Learn how to pre-fill form fields with existing task data.
- Handle form validation
Implement validation for the task update form.
You can now access the TaskForm component by clicking the Update
link.
This path includes a dynamic value to pass the id of the task to update.
The TaskForm component form is currently empty because it was created to add a new task and is therefore initialized as an empty form.
task = { id: "", title: "", description: "",};
Update it to use the form for both creating and updating a task.
Retrieve task information to update with TaskService
Section titled “Retrieve task information to update with TaskService”Before getting the route identifier, let’s prepare the logic to identify the task to update. Since the task list is stored in TaskService, you’ll add a new function to retrieve a task based on its id. From this identifier, you’ll get the task to fill the form.
-
Update the file
src/app/task-service.ts
.task-service.ts import { Injectable, signal, WritableSignal } from "@angular/core";import { Task } from "./task.model";@Injectable({providedIn: "root",})export class TaskService {tasks: WritableSignal<Task[]> = signal([{title: "Task 1",description: "Description of task 1",createdAt: new Date(),},{title: "Task 2",description: "Description of task 2",createdAt: new Date(),},]);addTask(task: Task): void {this.tasks.update((tasks) => {return [...tasks, {...task,createdAt: new Date(),});});}getTask(id: string): Task {return this.tasks().find((task) => task.id === id)!;}}
Get the task identifier from the route
Section titled “Get the task identifier from the route”The id is present in the route path, you need to retrieve it in the TaskFormComponent. Use the ActivatedRoute service to get the id from the route.
This service provides access to information about the current route. As you did with the Router, you’ll inject it into the TaskFormComponent constructor.
Hooks: Angular lifecycle
Section titled “Hooks: Angular lifecycle”Until now, you’ve initialized class properties during their declaration.
For example, you initialized the task property with an empty object:
task = { id: "", title: "", description: "",};
You can’t use such logic to initialize the task property with the task to update because this id
isn’t yet available when the Component class is created.
Why?
From creation to destruction, a component goes through several stages. When creating the Component class, route information is not yet available.
To handle such a case, Angular provides lifecycle hooks. Lifecycle hooks are methods that Angular calls in components and directives when it creates, changes, and destroys them.
One of the most used lifecycle hooks is ngOnInit, which is already present in all created components of the application. This hook is called right after Angular has instantiated the Component class. And at this point, the component is able to read route information.
Inside this hook, start by retrieving the route identifier and save it into a new variable called id
.
private id: string | null = null;
ngOnInit() { this.id = this.route.snapshot.paramMap.get('id');}
route.snapshot is a static image of route information and exposes a paramMap property.
This paramMap is a map of required and optional parameters specific to the route, including the dynamic route path parameters. The get method of the paramMap object allows us to retrieve the value of a parameter based on the name you used in the route path definition: id.
Then, you’ll retrieve the task to update from the TaskService based on the id available in the route.
private id: string | null = null;
ngOnInit() { this.id = this.route.snapshot.paramMap.get('id'); this.form.patchValue(this.taskService.getTask(this.id)); }
The TaskFormComponent is used for both creating and updating a task. You should test if the id is available in the route before retrieving the task to update. This will prevent an error when the id is not available in the route.
private id: string | null = null;
ngOnInit() { this.id = this.route.snapshot.paramMap.get('id');
if (this.id) { this.form.patchValue(this.taskService.getTask(this.id)); }}
Form validation
Section titled “Form validation”Form validation is the process of checking user input in a form to make sure it is complete and correct before allowing the form to be submitted. For example, you can require certain fields to be filled in or check that an email address is in the right format. Angular provides built-in tools to help you validate form input and display useful error messages to users
For example: Validators.required
is a built-in Angular validator used in reactive forms to make a form field mandatory. When applied, the form control is considered invalid if it is empty, helping ensure users fill out required fields before submitting the form. Validators.minLength(3)
is another built-in Angular validator that checks if the input value has a minimum length of 3 characters. If the input is shorter, the form control is marked as invalid, prompting users to enter a longer value.
In our case we won’t handle the error but we will console log the error if the form is invalid in our submit.
-
Update the file
src/app/task-form/task-form.ts
.import {Component, inject, OnInit} from '@angular/core';import {FormControl, FormGroup, ReactiveFormsModule} from '@angular/forms';import {TaskService} from '../task-service';import {Router} from '@angular/router';import { ActivatedRoute } from "@angular/router";@Component({selector: "app-task-form",imports: [ReactiveFormsModule,],templateUrl: "./task-form.html",styleUrl: "./task-form.css",})export class TaskForm implements OnInit {private taskService = inject(TaskService);private router = inject(Router);private route = inject(ActivatedRoute);private id: string | null = null;form = new FormGroup({title: new FormControl("", [Validators.required]),description: new FormControl("", [Validators.minLength(1)]),});ngOnInit() {this.id = this.route.snapshot.paramMap.get("id");if (this.id) {this.form.patchValue(this.taskService.getTask(this.id));}}submit() {if (this.form.invalid) {console.log('Your form is invalid. Please check the fields.');console.log('Your Form: ', this.form.value);console.log('Title Errors: ', this.form.controls.title.errors);console.log('Description Errors: ', this.form.controls.description.errors);}this.taskService.addTask(this.form.value);this.router.navigate(["/"]);}}
Test it
Section titled “Test it”- Click the
Update
button next to a task in the list. 2. The form should be filled with the task to update.
In this chapter, you learned how to update TaskFormComponent to fill the form with the task to update. You learned how to retrieve the task from TaskService based on the id available in the route.