Skip to content

Retrieve the Task List

Chapter Objectives

  • ✔️
    Retrieve the Task List
    Retrieve the task list from the mock API server.

Update TaskService

The HttpClient service exposes several functions that allow you to make HTTP requests to a server. In this chapter, you’ll use the get method to retrieve the task list from the API server.

This function takes the API server route path as a parameter: http://localhost:3000/tasks. This is the URL it will query to get the list of tasks.

getTasks(): Observable<Task[]> {
return this.http.get<Task[]>('http://localhost:3000/tasks');
}

This new getTasks method defines the communication with the API server:

  • It makes a GET request;
  • It expects an array of Task objects in response;
  • It communicates with the API server at the URL http://localhost:3000/tasks.

🎓 Instructions

  1. Update the file src/app/task.service.ts.

    import { Injectable } from "@angular/core";
    import { HttpClient } from "@angular/common/http";
    import { Task } from "./task.model";
    @Injectable({
    providedIn: "root",
    })
    export class TaskService {
    tasks: Task[] = [
    {
    id: "1",
    title: "First task",
    description: "This is the first task in your to-do list.",
    },
    {
    id: "2",
    title: "Second task",
    description: "This is the second task in your to-do list.",
    },
    ];
    constructor(private http: HttpClient) {}
    getTasks(): Observable<Task[]> {
    return this.http.get<Task[]>("http://localhost:3000/tasks");
    }
    }

Update TaskListComponent

Update TaskListComponent to use the new getTasks method and rename the tasks variable to tasks$. Adding $ indicates that it’s an Observable.

tasks$ = this.taskService.getTasks();

Why? What is an observable?

tasks was an array of Task objects. Now, tasks$ is an observable of an array of Task objects.

By calling the getTasks function, we get an Observable that will emit the list of tasks once received from the API server. To differentiate an observable value, the Angular community commonly uses the $ suffix in Angular applications.

🎓 Instructions

  1. Update the file src/app/task-list/task-list.component.ts.

    import { Component } from "@angular/core";
    import { TaskService } from "../task.service";
    import { Task } from "../task.model";
    @Component({
    selector: "app-task-list",
    templateUrl: "./task-list.component.html",
    styleUrls: ["./task-list.component.css"],
    })
    export class TaskListComponent {
    tasks: Task[] = this.taskService.tasks;
    tasks$ = this.taskService.getTasks();
    constructor(private taskService: TaskService) {}
    }

Subscription

Calling the getTasks function won’t trigger the API request immediately. Since it hasn’t been triggered yet, the observable won’t emit any values. Trigger what we call a subscription to the observable to start the request.

How to subscribe?

There are several ways to subscribe to an observable. For the given situation, use the async pipe in the HTML Template.

Like the date pipe used previously, the role of the async pipe is to transform data before displaying it. Here its role will be to subscribe to the observable and return the list of tasks once available.

🎓 Instructions

  1. Modify the file src/app/task-list/task-list.component.html.

    <tr *ngFor="let task of tasks$ | async">
    <td>{{ task.title }}</td>
    <td>{{ task.createdAt | date }}</td>
    <td>
    <a class="btn btn-primary" [routerLink]="['/update', task.id]">Update</a>
    <button
    class="btn btn-danger"
    type="button"
    (click)="deleteTask(task.id)"
    >
    Delete
    </button>
    </td>
    </tr>

Alternative

The alternative to using the async pipe is to subscribe to the observable in the component.

This is done by calling the subscribe function on the observable and passing a callback function as a parameter. This callback will be made once the data is available.

This subscription will be used in the ngOnInit function of the TaskListComponent class.

🎓 Instructions

  1. Modify the file src/app/task-list/task-list.component.ts.

    import { Component, OnInit } from "@angular/core";
    import { TaskService } from "../task.service";
    import { Task } from "../task.model";
    @Component({
    selector: "app-task-list",
    templateUrl: "./task-list.component.html",
    styleUrls: ["./task-list.component.css"],
    })
    export class TaskListComponent implements OnInit {
    tasks: Task[] = this.taskService.tasks;
    constructor(private taskService: TaskService) {}
    ngOnInit() {
    this.taskService.getTasks().subscribe((tasks) => (this.tasks = tasks));
    }
    }

Pitfalls

Although subscribing to the observable in the component is a valid solution, it lacks some optimizations provided by the async pipe. It also requires more code for the same result.

Indeed, when you use the subscription to the observable in the component, you need to think about unsubscribing. We won’t cover this action for now. You can discuss with your mentor for more details.

✔️ What you’ve learned

In this chapter, you’ve learned one of Angular’s key features: how to query data from an API server!