Angular 15 REST API By Example with HttpClient

Angular 15 REST API By Example with HttpClient

In this article, we'll see how to use Angular HttpClient to send GET requests to REST API servers in your Angular 15 application. We'll also look at Angular services, RxJS Observables, models, and the async pipe.

Front-end apps developed using frameworks like Angular connect with backend servers through REST APIs (based on the HTTP protocol) using either the XMLHttpRequest interface or the fetch() API.

The Angular HttpClient interface is based on the XMLHttpRequest interface, which is also supported by older browsers.

Throughout this angular tutorial, we'll look at practical examples of how to utilize the HttpClient class from the @angular/common/http package to perform HTTP GET requests with the get() method.

We'll also talk about:

  • How to create a fake but fully functional REST API,
  • How to create Angular services
  • Subscribing to Observables,
  • How to iterate through Observable data using the async pipe in templates.

Prerequisites

Before you can begin, there are a few prerequisites you must meet. You must have the following tools installed on your development system in order to work properly:

  • Node.js and npm. You can install both from the official website.
  • Angular CLI 15 (You can install it from npm using: npm install -g @angular/cli)

You'll also need to generate an Angular 15 project to complete the task.

If this is your first time working with the Angular CLI, just open your terminal and enter the following command to create a project:

$ ng new AngularHttpClientGetDemo

Setting up Angular 15 HttpClient

HttpClientModule must be included in your main application's module as the very first step. Changes should be made to the src/app/app.module.ts file as follows:

    import { HttpClientModule } from '@angular/common/http';
    @NgModule({
    declarations: [
    AppComponent
    ],
    imports: [
    BrowserModule,
    HttpClientModule
    ],
    bootstrap: [AppComponent]
    })
    export class AppModule { }

All done, we are now prepared to use the HttpClient in our angular 15 project.

Setting up a Fake REST API Server

A REST API server is required in order to demonstrate how to utilize the HttpClient library. You may use an external API service, create a realistic Rest API server, or create a fake API using the json-server library to accomplish the task. We'll choose the last approach in this example since it's less time-consuming than the first.

So, open up your terminal and begin by installing json-server using the Node Package Manager (npm) as follows:

$ npm install -g json-server 

Next define your data in a db.json file:

            {
            "products": [
                {
                "id": 1,
                "name": "Product001",
                "cost": 10.0,
                "quantity": 1000,
                "locationId" : 1,
                "familyId" : 1
                },
                {
                "id": 2,
                "name": "Product002",
                "cost": 20.0,
                "quantity": 2000,
                "locationId" : 1,
                "familyId" : 2
                },   
                {
                "id": 3,
                "name": "Product003",
                "cost": 30.0,
                "quantity": 3000,
                "locationId" : 3,
                "familyId" : 2     
                },
                {
                "id": 4,
                "name": "Product004",
                "cost": 40.0,
                "quantity": 4000,
                "locationId" : 2,
                "familyId" : 3
                }
            ],
            "locations":[
                {
                "id": 1,
                "name": "Location001"
                },
                {
                "id": 2,
                "name": "Location002"
                },
                {
                "id": 3,
                "name": "Location003"
                }
            ],
            "families":[
                {
                "id": 1,
                "name": "FM001"
                },
                {
                "id": 2,
                "name": "FM002"
                },
                {
                "id": 3,
                "name": "FM003"
                }
            ],
            "transactions":[
                {
                "id": 1,
                "cost":11,
                "quantity":10,
                "productId":1
                },
                {
                "id": 2,
                "cost":12,
                "quantity":100,
                "productId":2
                },    
                {
                "id": 3,
                "cost":15,
                "quantity":101,
                "productId":3
                }  
            ]
            }

Following that, you may start a REST server by running the following command:

$ json-server --watch db.json 

The HttpClient get() Method

The HttpClient get() function is intended to be used to send HTTP GET requests to the server. As an example, consider the following syntax:

        get(url: string, options: {
            headers?: HttpHeaders;
            observe: 'response';
            params?: HttpParams;
            reportProgress?: boolean;
            responseType?: 'json';
            withCredentials?: boolean;
        }): Observable<HttpResponse<Object>>;

It takes a REST API endpoint and an optional options object and returns an Observable instance.

Now let's take a real world example. Let's presume you want to access the API endpoints we created above:

First you need to import HttpClient in your component.

import { HttpClient } from '@angular/common/http';

Next you need to inject HttpClient via the component's constructor

  constructor(private httpClient: HttpClient){}

Next, add a method where you can call HttpClient.get(ENDPOINT_URL):

    get_products(){
        this.httpClient.get(this.baseUrl + '/products').subscribe((res)=>{
            console.log(res);
        });
    }

When called, this method will make a GET request to the /products endpoint then subscribe to the returned Observable. It will then log the array of products to the console.

Now let's make a button to callthe get_products() method:

    <button (click)="get_products()">GET /products</button>

Now, If you want to show the products on the component template.

First, add a products array:

    private products  = []; 

Next change the get_products() method as follows:

    get_products(){
        this.httpClient.get(this.baseUrl + '/products').subscribe((res : any[])=>{
        console.log(res);
        this.products = res;
        });
    }

We simply assing the returned products to the products array.

Next, use the ngFor directive in your component template to loop through the products array:

    <ul>
      <li *ngFor="let product of products" >
        -- id: {{product.id}}
        -- name: {{product.name}}
        -- cost: {{product.cost}}
        -- quantity: {{product.quantity}}
      </li>
    </ul> 

The async pipe and Observables

In our example, We can access the data returned by the get() method in two ways.

Subscribe to the returned Observable, i.e:

     get_products(){
        this.httpClient.get(this.baseUrl + '/products').subscribe((res : any[])=>{
            console.log(res);
            this.products = res;
        });
    }

Or use the async pipe with the returned Observable and iterate directly over data in the template. Let's see how in more details.

First, you need to create an Observable using the following:

     private productsObservable : Observable<any[]> ; 

Next, call the get() method and assign the result to productsObservable:

     this.productsObservable = this.httpClient.get(this.baseUrl + '/products');

Finally, in your template:

      <li *ngFor="let product of productsObservable | async" >
        -- id: {{product.id}}
        -- name: {{product.name}}
        -- cost: {{product.cost}}
        -- quantity: {{product.quantity}}
      </li>

We loop through the products using the Angular ngFor directive.

Using Angular 15 Services

Using code that access data directly in your components is against the separation of concerns rule so let's refactor our code to use an Angular service which makes HTTP GET requests then returns the result back to our component(s).

Using Angular CLI, generate a new service:

$ ng generate service data 

Next move the data access code to this service. Open the src/app/data.service.ts file and update it accordingly:

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';

    @Injectable({
        providedIn: 'root'
    })
    export class DataService {
    baseUrl:string = "http://localhost:3000";

    constructor(private httpClient : HttpClient) {}

    get_products(){
        return this.httpClient.get(this.baseUrl + '/products');
    }
    get_families(){
        return this.httpClient.get(this.baseUrl + '/families');
    }
    get_locations(){
        return this.httpClient.get(this.baseUrl + '/locations');
    }
    get_transactions(){
        return this.httpClient.get(this.baseUrl + '/families');
    }

    }

Next, change the src/app/app.component.ts file as follows:

    import { Component } from '@angular/core';
    import { Observable } from 'rxjs';

    import { DataService } from './data.service';

    /* .... */
    @Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
    })
    export class AppComponent {    
        private products  = []; 
        private families = [];
        private locations = [];
        private transactions = [];

        private productsObservable : Observable<any[]> ; 

        constructor(private dataService: DataService){

            this.productsObservable = this.dataService.get_products();

            this.dataService.get_families().subscribe((res : any[])=>{
                this.families = res;
            });
            this.dataService.get_locations().subscribe((res : any[])=>{
                console.log(res);
                this.locations = res;
            });
            this.dataService.get_transactions().subscribe((res : any[])=>{
                console.log(res);
                this.transactions = res;
            });    
        }
    }

Instead of injecting HttpClient directly in our component we inject our data service and call its methods to make GET requests to our REST API server.

Creating Angular Models

Now let's further refactor our code to use models for products, families, locations and transactions.

In the root of Angular project, create these models:

src/app/product.ts

    export interface Product {
        id: number;
        name: string;
        cost: number;
        quantity: number;
        locationId: number;
        familyId: number;
    } 

src/app/family.ts

    export interface Family {
        id: number;
        name: string;
    } 

src/app/location.ts

    export interface Location {
        id: number;
        name: string;
        constructor() { }
    } 

src/app/transaction.ts

    export interface Transaction {
        id: number;
        cost: number;
        productId: number;
        quantity: number;
    } 

Next update your the src/app/app.component.ts file to use the new models:

    import { Product } from './product';
    import { Family } from './family';
    import { Location } from './location';
    import { Transaction } from './transaction';


    private products : Product[] = []; 
    private families : Family[] = [];
    private locations : Location[] = [];
    private transactions : Transaction[] = [];

    private productsObservable : Observable<Product[]> ; 

    constructor(private dataService: DataService){

        this.productsObservable = this.dataService.get_products();

        this.dataService.get_families().subscribe((res : Family[])=>{
            this.families = res;
        });
        this.dataService.get_locations().subscribe((res : Location[])=>{
            this.locations = res;
        });
        this.dataService.get_transactions().subscribe((res : Transaction[])=>{
            this.transactions = res;
        });    
    }

You can find the complete source code of this demo in GitHub.

Conclusion

We demonstrated how to send GET requests to REST API servers from inside your Angular 15 application, and we looked at how to utilize HttpClient, Angular services, RxJS Observables, models, and the async pipe, among other things.

REST APIs are used by front-end applications written using frameworks such as Angular to communicate with backend servers. We can utilize either the XMLHttpRequest interface or the fetch() API to communicate with backend servers.

Since older browsers are also able to make use of the XMLHttpRequest interface, it was used as the foundation of the Angular HttpClient.

We also discussed the following topics:

  • How to develop a fake but completely working REST API.
  • How to create Angular Services; in addition to subscribing to observables,
  • How to iterate over Observable data in templates by utilizing the async pipe.


✋If you have any questions about this article, ask them in our GitHub Discussions 👈 community. You can also Gitter

✋ Want to master Angular 14? Read our angular tutorial and join our #DailyAngularChallenge where we learn to build components, directives, services, pipes and complete web, mobile, and desktop applications with latest Angular version.

✋ Make sure to join our Angular 14 Dev Community 👈 to discuss anything related to Angular development.

❤️ Like our page and subscribe to our feed for updates!

Find a list of emojis to copy and paste