The Angular HttpClient Module is introduced in the Angular 4.3. This new API is available in package @angular/common/http and intends to replace the older HttpModule. In this Angular HttpClient Tutorial, we learn how to use HttpClient.Get method to query the GitHub API Source to get data into our Application. Like the older HtppModule, the newer HttpClientModule also uses the RxJs Observables. The Response returned from the HttpClient is an observable, hence needs to be Subscribed. We will learn all these in this Tutorial.
Applies to : Angular 5, Angular 6, Angular 7, Angular8, Angular9
We learned how to Build Components, How to Create and inject services, use pipes and directives to build Angular Application. You can read the entire Tutorial on Angular.
Using Angular HttpClient
The HttpClient is a separate model in Angular and is available under the @angular/common/http package. All you need to do is to import it and inject it into our component/service. Then, Use HttpClient.Get method to send an HTTP Request and Subscribe to the response Asynchronously. And when the response arrives map it the desired object and displays the result.
Here are the steps in detail
Import HttpClient Module in Root Module
We need to import it into our root module app.module. Also, we need to add it to the imports metadata array.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import { NgModule } from '@angular/core'; import { HttpModule } from '@angular/http'; @NgModule({ declarations: [ AppComponent ], imports: [ HttpClientModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { } |
Import Required Module in Component/Service
Then you should import the @angular/common/http & rxjs/Rx modules in our component class as shown below
1 2 3 4 | import { HttpClient } from '@angular/common/http'; import { Observable} from 'rxjs/Rx'; |
Inject HttpClient service into your component/service
1 2 3 4 | constructor(public http: HttpClient) { } |
Call the HttpClient.Get method
We send the HttpClient.get request to our Service API endpoint. The HttpClient.Get method returns an Observable, which is subscribed. The Result arrives in JSON format which is displayed to the user.
1 2 3 4 5 6 7 8 9 10 11 12 | public getData() { this.HttpClient.get<any[]>(this.baseUrl+'users/'+this.userName+'/repos') .subscribe(data => { this.data= data; }, error => { } ); } |
That’s it.
HttpClient.get
The HttpClient.get sends the HTTP Get Request to the API endpoint and parses the returned result to the desired type. The default response type is JSON. If you want any other type, then you need to specify explicitly using the responseType parameter.
Parameters of the HttpClient.get
headers
It allows you to add HTTP headers to the outgoing requests.
observe
The HttpClient.get method returns the body of the response parsed as JSON (or type specified by the responseType). Sometimes you may need to read the entire response along with the headers and status codes. To do this you can set the observe property to the response.
The allowed options are
- a response which returns the entire response
- body which returns only the body
- events which return the response with events.
params
Allows us to Add the URL parameters to the Get Request
reportProgress
This is a boolean property. Set this to true, if you want to get notified of the progress of the Get Request. This is a pretty useful feature when you have a large amount of data to download (or upload) and you want the user to notify of the progress.
responseType
Json is the default response received. In case you want a different type of response, then you need to use this parameter. The Allowed Options are arraybuffer, blob, json, and text.
withCredentials
It is of boolean type. If the value is true then HttpClient.get will request data with credentials
Return from the httpClient.Get
Notice that when we use Angular HttpClient Services to get data, it actually returns an Observables.
Best Angular Books
The Top 8 Best Angular Books, which helps you to get started with Angular
What is Observable?
Observable help us to manage async data. You can think of Observables as an array of items, which arrive asynchronously over time.
The observables implement the observer design pattern, where observables maintain a list of dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods
Observer subscribes to an Observable. The observer reacts when the value of the Observable changes. An Observable can have multiple subscribers and all the subscribers are notified when the state of the Observable changes.
The Observables are used extensively in Angular. The new HTTP service and Event system are all Observable based.
The Observables are Proposed Feature for the next version of Javascript. The Angular Uses Third-party library called Reactive Extensions or RxJs to implement the Observables. You can learn about RxJs from these RxJx tutorials
Observables Operators
Operators are methods that operate on an Observable and return an observable. Each Operator modifies the value it receives. These operators are applied one after the other in a chain.
The RxJs Provides several Operators, which allows you to filter, select, transform, combine and compose Observables. Examples of Operators are map, filter, take, merge, etc
How to use RxJs
The RxJs is a very large library. Hence Angular exposes a stripped-down version of Observables. You can import it using the following import statement
1 2 3 | import { Observable} from 'rxjs/Rx'; |
The above import imports only the necessary features. It does not include any of the Operators.
To use observables operators, you need to import them. The following code imports the map operator.
1 2 3 | import 'rxjs/add/operator/map'; |
Angular HttpClient Example
Now, We have a basic understanding of HttpClient model & observables, let us build an HttpClient Service.
The source code for this tutorial is available at GitHub. The Start folder contains the initial code and the final code is in the HTTP folder
Let us query the GitHub repository to get the details of the repositories for a selected user.
Repository Model
Create repos.ts file and add the following code. This is a simplified model for the GitHub repository.
1 2 3 4 5 6 7 8 | export class repos { id: string; name: string; html_url: string; description: string; } |
GitHub Service
Create githubservice.ts and add the following code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable} from 'rxjs/Rx'; import { repos} from './repos'; @Injectable() export class GitHubService { baseURL:string="https://api.github.com/"; constructor(private http:HttpClient){ } getRepos(userName:string): Observable<repos[]> { return this.http.get<repos[]>(this.baseURL + 'users/' + userName + '/repos') } } |
First, we import required HttpClient module from @angular/common/http package. We also need Injectable as we will be injecting HttpClient via Dependency Injection
1 2 3 4 | import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; |
The Observable is included from the RxJs library.
1 2 3 | import { Observable} from 'rxjs/Rx'; |
Set the baseURL variable to the GitHub API endpoint.
1 2 3 | baseURL:string="https://api.github.com/"; |
Inject HttpClient into the service.
1 2 3 4 | constructor(private httpClient:HttpClient){ } |
Next, is the GetRepos method, which takes the username as the argument and returns an Observable<repos[]> observable of Repos.
1 2 3 4 5 | getRepos(userName:string): Observable<repos[]> { return this.httpClient.get<repos[]>(this.baseURL + 'users/' + userName + '/repos') } |
Inside the getRepos method, we invoke httpClient.get method.
The HttpClient.get method allows us to cast the returned response object to a type we require. We make use of that feature and supply the type for the returned value httpClient.get<repos[]>
Finally, We pass the URL as the parameter to the get method.
Component
Add the following code to app.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import { Component } from '@angular/core'; import { Observable} from 'rxjs/Rx'; import { GitHubService } from './github.service'; import { repos} from './repos'; @Component({ selector: 'app-root', templateUrl: './app.component.html', }) export class AppComponent { userName: string ="tektutorialshub" repos: repos[]; loading: boolean=false; errorMessage; constructor(private githubService: GitHubService) { } public getRepos() { this.loading=true; this.errorMessage=""; this.githubService.getRepos(this.userName) .subscribe((response) => {this.repos=response;}, (error) => {this.errorMessage=error; this.loading=false; }, () => {this.loading=false;}) } } |
We are using Dependency injection to inject our newly created gitHubService into the component.
We have four variables.
userName: GitHub username
Repos: variable to hold the data received from GitHub
Loading: to display the loading indicator to the user
errorMessage: to display the user-friendly error message
GetRepos method
We make a call to GetRepos to retrieve the Repos. We start with initializing the loading variable to true so that we can display a loading indicator to the user.
Next, Invoke the getRepos method of the gitHubService, with the userName as the argument.
1 2 3 | this.githubService.getRepos(this.userName) |
This method returns Observable<repos>. We then subscribe to it.
Subscribe method
The Subscribe operator is the glue that connects an observer to an Observable
We need to Subscribe to an observable to see the results of observables.
1 2 3 4 5 | .subscribe((response) => {this.repos=response;}, (error) => {this.errorMessage=error; this.loading=false; }, () => {this.loading=false;}) |
The subscribe method has three arguments. Each specifies the action to be taken when a particular event occurs
1 2 3 | .subscribe(success, failure, completed); |
Success: This event is raised whenever observable returns a value. We use this event to assign the response to the repos
1 2 3 | (response) => {this.repos=response;} |
Failure: This event occurs, when observable is failed to generate the expected data or has encountered some other error. The error message is assigned to the local variable errorMessage so as to display the result to the user. The loading indicator is also disabled as the observable now terminates due to the error
1 2 3 | (error) => {this.errorMessage=error; this.loading=false; }, |
Completed: This event fires, when the observables complete its task. We disable the loading indicator here.
1 2 3 | () => {this.loading=false;}) |
Template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | <h1 class="heading"><strong>HTTP </strong>Demo</h1> <div class="form-group"> <label for="userName">GitHub User Name</label> <input type="text" class="form-control" name="userName" [(ngModel)]="userName"> </div> <div class="form-group"> <button type="button" (click)="getRepos()">Get Repos</button> </div> <div *ngIf="loading">loading...</div> <div *ngIf="errorMessage" class="alert alert-warning"> <strong>Warning!</strong> {{errorMessage}} </div> <div class='table-responsive'> <table class='table'> <thead> <tr> <th>ID</th> <th>Name</th> <th>HTML Url</th> <th>description</th> </tr> </thead> <tbody> <tr *ngFor="let repo of repos;"> <td>{{repo.id}}</td> <td>{{repo.name}}</td> <td>{{repo.html_url}}</td> <td>{{repo.description}}</td> </tr> </tbody> </table> </div> <pre>{{repos | json}}</pre> </div> |
The input box asks for the GitHub username. Two-way binding is used here to map it the userName in the component class.
1 2 3 4 5 6 | <div class="form-group"> <label for="userName">GitHub User Name</label> <input type="text" class="form-control" name="userName" [(ngModel)]="userName"> </div> |
A button binds to the click event to make a call to getRepos method on the Component
1 2 3 4 5 | <div class="form-group"> <button type="button" (click)="getRepos()">Get Repos</button> </div> |
The loading Indicator using the ngIf directive to hide or show the “loading …” message
1 2 3 | <div *ngIf="loading">loading...</div> |
The error messages are displayed to the user only if they are present. Again using the ngIf Directive
1 2 3 4 5 | <div *ngIf="errorMessage" class="alert alert-warning"> <strong>Warning!</strong> {{errorMessage}} </div> |
Finally, we display the list of GitHub Repos using the ngFor Directive
1 2 3 4 5 6 7 8 | <tr *ngFor="let repo of repos;"> <td>{{repo.id}}</td> <td>{{repo.name}}</td> <td>{{repo.html_url}}</td> <td>{{repo.description}}</td> </tr> |
Inspect the received data using the Json pipe
1 2 3 | <pre>{{repos | json}}</pre> |
Module
Finally, we need to make few changes in our root Module (appModule)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpClientModule} from '@angular/common/http'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { GitHubService } from './github.service'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule, FormsModule ], providers: [GitHubService], bootstrap: [AppComponent] }) export class AppModule { } |
We need to import the HttpClientModule from the @angular/common/http
1 2 3 | import { HttpClientModule} from '@angular/common/http'; |
And add it to the Imports metadata
imports: [ BrowserModule, HttpClientModule, FormsModule ]We need to import the GitHubService
1 2 3 | import { GitHubService } from './github.service'; |
And register it with the Providers array. This will make the service singleton and can be injected via dependency injection
1 2 3 | providers: [GitHubService], |
Finally, you can run the code.
You can test the error message by making the Url invalid.
Summary
We learned how to create a simple HTTP Service in this tutorial. We also looked at the basics of Observables which is not extensively used in Angular
You can download the source code from this link