Angular 2+ By Example:Making HTTP GET Requests using HttpClient -- Words (1698)

Angular
How to use HttpClient to make HTTP GET requests in Angular 2+

Front end applications, built using frameworks like Angular 2 communicate with backend servers through Rest APIs based on HTTP protocol and supported, in modern browsers, either by XMLHttpRequest interface or fetch() API.

Throughtout this tutorial, we are going to see practical examples of how to use HttpClient, available from @angular/common/http, to make HTTP GET requests using .get() method.

We'll also cover how to generate a fake and complete working Rest API, create Angular 2+ data Services, Subscribing to Observables and using async pipe in templates to iterate over Observable data.

Prerequisites

Before getting started you need a few requirements: you need to have the following installed on your system

Node.js,

TypeScript,

Angular CLI

You also need to create an Angular 2+ project.

In case, this is your first time using the Angular CLI, simply open your terminal then run:

ng new AngularHttpClientGetDemo
Please note that we are using HttpClient which is an improved version of HTTP Client API and available starting with Angular version 4.3.0-rc.0

Setting up HttpClient

The first step is to include HttpClientModule in AppModule.

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

That's all, we are now ready to use HttpClient.

Setting up a Fake Rest API

To test HttpClient API we need an API, you can either use an external API service, create a real Rest API server or create a fake API using json-server. I'm going to use the last approach because it's less time consuming.

So head over to your terminal and start by installing json-server from npm:

npm install -g json-server 

Next define your objects in db.json :

        {
        "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
            }  
        ]
        }

then run the server:

json-server --watch db.json 

HttpClient .get() method

The HttpClient .get() method is used to make HTTP GET requests, the syntax is as follows:

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

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

Now lets take a real world example, lets say we want to access the API endpoints we created above, these are the steps we need to follow:

First we need to import HttpClient.

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

Next we need to inject HttpClient

constructor(private httpClient: HttpClient){}

Then 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 /products endpoint then subscribe to response. It will then log the array of products to the console.

Now lets make a button to call get_products()

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

We want to show the products on html view:

Declare a products array :

private products  = []; 

Next change get_products() method:

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

Then add the following in your component html template:

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

async pipe and Observables

We can access data returned by .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 Observable and iterate directly over data.

First declare an Observable with:

 private productsObservable : Observable<any[]> ; 

Call .get() method and assign the result to productsObservable:

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

Then in template:

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

Use services

Using data access code directly in components is against separation of concerns rules so lets refactor our code to use a data service which makes HTTP GET requests then returns the result back to our component.

Using Angular CLI generate a new service:

ng generate data 

Then provide it in app.module.ts

/* --- */

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

/* --- */

@NgModule({
declarations: [
    AppComponent
],
imports: [
    BrowserModule,
    HttpClientModule
],
providers: [DataService],
bootstrap: [AppComponent]
})
export class AppModule { }

Next move the data access code to this service:

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

@Injectable()
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');
}

}

Then change app.component.ts

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;
        });    
    }
}

So 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 data Types

Now lets further refactor our code to use custom types for products, families, locations and transactions:

In the root of Angular project, create these data types:

app/product.ts

export class Product {
    id: number;
    name: string;
    cost: number;
    quantity: number;
    locationId: number;
    familyId: number;
    constructor() { }
} 

app/family.ts

export class Family {
    id: number;
    name: string;
    constructor() { }
} 

app/location.ts

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

app/transaction.ts

export class Transaction {
    id: number;
    cost: number;
    productId: number;
    quantity: number;
    constructor() { }
} 

Next update your app/app.component.ts to use the new Types:

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.

DOWNLOAD SOURCE CODE

Conclusion

So we have seen a practical examples of how to use HttpClient .get() to make HTTP GET request to a Rest API server.



mrnerd is a Web Entrepreneur & Developer, Digital Marketer and a Passionate Blogger. He writes about software and website development,money making tips and SEO etc.. He is a tech addict and a computer geek with a lot of hobbies.