Angular Labs
COOKIES

Update a Task with HTTP Client

Git diff Branch
Chapter Objectives
  • Update a task using HTTP Client

    Update a task in the list by making an API call to the mock server.

In addition to targeting task updates rather than creation, this lesson will be quite similar to the previous one:

  • You will update TaskService
  • You will update TaskForm component while paying attention to the asynchronous HTTP request.

TaskService

Based on the HTTP protocol, you will use the put function to add a task to the list: http.put(). This function expects 2 parameters:

  1. The API server URL; This URL will include the ID of the task to update: http://localhost:3000/tasks/${task.id}
  2. The task object to send to the server
updateTask(task: Partial<Task>, id: string) {
return this.http.patch<Task>(`http://localhost:3000/tasks/${id}`, task);
}
  1. Update the task.service.ts file.

    import { Injectable, inject } from "@angular/core";
    import { HttpClient } from "@angular/common/http";
    import { Task, TaskForm } from "./task.model";
    @Injectable({
    providedIn: "root",
    })
    export class TaskService {
    private http = inject(HttpClient);
    getTask(id: string) {
    return this.http.get<Task>(`http://localhost:3000/tasks/${id}`);
    }
    updateTask(task: Partial<Task>, id: string) {
    return this.http.patch<Task>(`http://localhost:3000/tasks/${id}`, task);
    }
    }

Retrieving the Task to Update

You just updated the getTask function to retrieve a specific task. Like the previously changed functions to communicate with the API, this function will now alter the existing code in the TaskFormComponent. While the function name doesn’t change, you’ll now need to subscribe to get its value.

ngOnInit() {
const id = this.route.snapshot.paramMap.get('id');
if (id) {
this.taskService.getTask(id).subscribe(task => {
this.taskForm.patchValue(task);
});
}
}
  1. Update the task-form.ts file.

    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute, Router } from '@angular/router';
    import { TaskForm } from '../task.model';
    import { TaskService } from '../task.service';
    @Component({
    selector: 'app-task-form',
    templateUrl: './task-form.html',
    styleUrls: ['./task-form.css']
    })
    export class TaskForm implements OnInit {
    private taskService = inject(TaskService);
    private router = inject(Router);
    private route = inject(ActivatedRoute);
    taskForm = new FormGroup({
    title: new FormControl('', [Validators.required]),
    description: new FormControl('', [Validators.required])
    });
    ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id');
    if (id) {
    this.taskService.getTask(id).subscribe(task => {
    this.taskForm.patchValue(task);
    });
    }
    }
    }

TaskForm

Update TaskForm component to use the new function. The simplest way would be to apply the same logic as in the previous lesson, updating the submit function to make an API call and navigate to the list page.

This would give the following code:

submit() {
if (task.id) {
this.taskService.updateTask(this.taskForm.value, id).subscribe(() => {
this.router.navigate(['/']);
});
} else {
this.taskService.addTask(this.taskForm.value).subscribe(() => {
this.router.navigate(['/']);
});
}
}

This works but it’s not the best way to proceed as we’re duplicating the navigation logic. If the list page path changes, we would need to update it in two places. Handle it by modifying the submit function:

  • Create a variable whose value will be either the updateTask or addTask function. Its value will therefore be an Observable that you can subscribe to.
  • Subscribe to this variable and navigate to the list page.
  1. Update the task-form.ts file.

    import { Component } from "@angular/core";
    import { Router } from "@angular/router";
    import { TaskForm } from "../task.model";
    import { TaskService } from "../task.service";
    @Component({
    selector: "app-task-form",
    templateUrl: "./task-form.html",
    styleUrls: ["./task-form.css"],
    })
    export class TaskForm {
    private taskService = inject(TaskService);
    private router = inject(Router);
    private route = inject(ActivatedRoute);
    taskForm = new FormGroup({
    title: new FormControl('', [Validators.required]),
    description: new FormControl('', [Validators.required])
    });
    submit() {
    const id = this.route.snapshot.paramMap.get("id");
    const taskObservable = id
    ? this.taskService.updateTask(this.taskForm.value, id)
    : this.taskService.addTask(this.taskForm.value);
    taskObservable.subscribe(() => {
    this.router.navigate(["/"]);
    });
    }
    }
What you've learned

You have learned how to send a PUT request with HttpClient to update a task in an Angular application.