Source: https://www.concretepage.com/angular-2/angular-httpclient-get-example
This page will walk through Angular HttpClient.get
example. HttpClient
has been introduced in Angular 4.3 version. HttpClient
is smaller, easier and more powerful library for making HTTP requests. To use HttpClient
we need to import HttpClientModule
in our application module and then we can inject HttpClient
in our components or services. HttpClient
has methods such as get
, post
, delete
, put
etc. We will discuss here get
method.HttpClient.get
constructs an Observable
with configured GET request and when the Observable
instance is subscribed, GET
request is executed on the server. Here on this page we will provide the use of HttpClient.get
in detail with error handling. For Web Service test URL we will use Angular In-Memory Web API. Now find the complete example step by step.
Technologies Used
Find the technologies being used in our example.
1. Angular 5.0.0
2. Angular CLI 1.5.4
3. TypeScript 2.4.2
4. Node.js 6.11.0
5. NPM 3.10.10
6. In-Memory Web API 0.5.3
HttpClient.get
HttpClient
serves the purpose to perform HTTP requests. HttpClient
is injectable class. To perform http GET request, HttpClient
provides HttpClient.get
method that accepts URL and options for parameter, header etc and returns an Observable
instance. When we subscribe Observable
then GET
request is executed on the server. Find the syntax of HttpClient.get
from Angular doc.
get(url: string, options: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: HttpObserve;
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType?: 'arraybuffer' | 'blob' | 'json' | 'text';
withCredentials?: boolean;
} = {}): Observable<any>
We can see that HttpClient.get
accepts URL and other options such as parameter, headers etc. HttpClient.get
has following options to request http GET method.
headers: It is of HttpHeaders
types. It sets headers for the http GET request.
observe: It defines whether we want complete response or body only or events only. We need to assign values for observe
property such as response for complete response, body for response with body and events for response with events.
params: It is of HttpParams
type. It sets parameters in URL for http GET request.
reportProgress: It is of boolean type. It is useful when we are requesting blob data. Setting reportProgress
value as true we can know progress report for our HttpClient.get
request.
responseType: It is used to define response type of HttpClient.get
request. Its values can be arraybuffer, blob, json and text.
withCredentials: It is of boolean type. If the value is true then HttpClient.get
will request data with credentials.
The response type of HttpClient.get
is Observable
i.e. provided by RxJS library. Observable
is a representation of any set of values over any amount of time.
HttpClientModule
To use HttpClient
we need to import HttpClientModule
in our application module. Find the code snippet.
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [
HttpClientModule,
------
],
------
})
export class AppModule { }
Now we can inject HttpClient
in our components or services.
Injecting HttpClient
We inject HttpClient
using constructor into our component or service. HttpClient
is imported from @angular/common/http
library as following.
import { HttpClient } from '@angular/common/http';
Find the constructor to inject HttpClient
.
constructor(private http: HttpClient) {
}
Now we are ready to call HttpClient
methods using http
instance. For example, find the code below.
getWriterWithFavBooks(): Observable<any> {
return this.http.get(this.writerUrl);
}
Requesting JSON using HttpClient.get
Find the sample JSON data.
{
writerId: 11, writerName: 'Mahesh',
books: [
{ id: '103', name: 'Angular Tutorial', category: 'Angular', year: '2016' },
{ id: '104', name: 'Core Java Tutorial', category: 'Java', year: '2015' }
]
}
Suppose we have following URL to access the JSON data.
writerUrl = "/api/writer";
Now we can access JSON using HttpClient.get
as following.
writerUrl = "/api/writer";
getWriterWithFavBooks(): Observable<any> {
return this.http.get(this.writerUrl, {responseType: 'json'});
}
If response type is JSON then using responseType: 'json'
is optional we can also write it as following.
getWriterWithFavBooks(): Observable<any> {
return this.http.get(this.writerUrl);
}
Now subscribe to instance of Observable
for actual hit of request to server and get response.
getWriterWithFavBooks() {
this.writerService.getWriterWithFavBooks().subscribe(
data => {
this.favBooks = data['books'];
}
);
}
If we want Typechecking of response then we can do it by using type parameter. Suppose we have following interfaces.
export interface Book {
id: number;
name: string;
category: string;
year: string;
}
export interface Writer {
writerId: number;
writerName: string;
books: Book[];
}
We can tell the HttpClient.get
to return response as Writer
. Find the code snippet.
getFavoriteWriter(): Observable<Writer> {
return this.http.get<Writer>(this.writerUrl, {responseType: 'json'});
}
When we use http.get<Writer>(...)
then it returns the instance of Observable<Writer>
type. Now subscribe to Observable<Writer>
to get instance of Writer
.
getFavoriteWriter() {
this.writerService.getFavoriteWriter().subscribe(
data => {
this.favWriter = data;
console.log(this.favWriter.books);
}
);
}
Display data in HTML template as following.
<div *ngIf="favWriter">
Writer Id: <b>{{favWriter.writerId}}</b>, Writer Name: <b>{{favWriter.writerName}}</b>
<ul>
<li *ngFor="let book of favWriter.books" >
Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}}, Year: {{book.year}}
</li>
</ul>
</div>
Using async Pipe with Observable
HttpClient.get
returns instance of Observable
. To display this data either we can subscribe to Observable
or we can use async
pipe with Observable
. We have already provided sample code above to display data by subscribing Observable
. Here find the code to display data using async
pipe. Suppose we have following JSON data.
[
{ id: '103', name: 'Angular Tutorial', category: 'Angular', year: '2016' },
{ id: '104', name: 'Core Java Tutorial', category: 'Java', year: '2015' }
]
The JSON data is of Book
array type. We will provide type parameter as Book[]
. Now find the code for HttpClient.get
.
bookUrl = "/api/books";
getBooks(): Observable<Book[]> {
return this.http.get<Book[]>(this.bookUrl);
}
Now access the method and assign the value to Observable
property.
obsBooks: Observable<Book[]>
getBooks() {
this.obsBooks = this.writerService.getBooks();
}
Use async
pipe to display data in HTML template.
<ul>
<li *ngFor="let book of obsBooks | async" >
Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}}, Year: {{book.year}}
</li>
</ul>
Requesting Text data using HttpClient.get
To access text data using HttpClient.get
we need to use responseType: 'text'
. Suppose we have following text.
Welcome to the Angular world!
Find the URL to access the above text.
textUrl = "/api/message";
Now use HttpClient.get
with responseType: 'text'
as following.
getTextMsg(): Observable<string> {
return this.http.get(this.textUrl, {responseType: 'text'});
}
To display data, we can use either async
pipe with Observable
or we can subscribe it to get text data. Find the sample example.
obsTextMsg: Observable<string>
getTextMsg() {
this.obsTextMsg = this.writerService.getTextMsg();
this.writerService.getTextMsg().subscribe(
msg => console.log(msg)
);
}
Observable
instance i.e. obsTextMsg
can directly be displayed on HTML template using async
pipe as following.
<h3 *ngIf="obsTextMsg | async as message"> {{ message }} </h3>
HttpParams and HttpHeaders
Angular provides HttpParams
class to use parameters and it provides HttpHeaders
class to use headers with HttpClient.get
request. Both HttpParams
and HttpHeaders
classes are immutable and imported from @angular/common/http
library. Both have methods such as set
and append
. set
constructs a new body with a new value and append
constructs a new body with an appended value. We will import HttpParams
and HttpHeaders
as following.
import { HttpHeaders, HttpParams } from '@angular/common/http';
Now find sample example to use HttpParams
and HttpHeaders
with HttpClient.get
request.
filterBooks(category: string, year: string): Observable<Book[]> {
let httpHeaders = new HttpHeaders()
.set('Accept', 'application/json');
let httpParams = new HttpParams()
.set('category', category)
.set('year', year);
console.log(httpParams.toString());
console.log(httpHeaders.keys());
return this.http.get<Book[]>(this.bookUrl, {
headers: httpHeaders,
params: httpParams,
responseType: 'json'
});
}
HttpClient.get with observe Property
HttpClient.get
method can use observe
property to define whether we want complete response or body only or events only. We need to assign values for observe
property such as observe : 'response' for complete response. observe : 'body' for response with body. observe : 'events' for response with events. Suppose we want complete response of our request then we will use observe
property with HttpClient.get
as following.
getFullResponseForWriter(): Observable<HttpResponse<any>> {
return this.http.get(this.writerUrl, {
observe: 'response'
});
}
HttpResponse
is from @angular/common/http
library. Now we will fetch body as well as headers of the response as following.
writer: Writer;
getWriter() {
this.writerService.getFullResponseForWriter().subscribe(
res => {
this.writer = res.body;
console.log(this.writer.books);
console.log(res.headers.get('Content-Type'));
},
err => {
console.log(err);
}
);
}
Error Handling
To handle error, Angular provides HttpErrorResponse
class from @angular/common/http
library. HttpErrorResponse
contains useful information regarding error. The second parameter in subscribe()
is for error. We can log error as following.
getFavoriteWriter() {
this.writerService.getFavoriteWriter().subscribe(
data => {
this.favWriter = data;
},
err => {
console.log(err);
}
);
}
HttpClient.get
can face two types of errors.
a. If backend returns unsuccessful response codes such as 404, 500 etc then HttpClient.get
will throw error with backend response code.
b. If something goes wrong client-side, for example, an exception is thrown by RxJS operators or if network error prevents the request from completing successfully then actual Error
object is thrown by HttpClient.get
.
We can check if error is of Error
type or not by using HttpErrorResponse
and accordingly log the error messages.HttpErrorResponse
can be imported from @angular/common/http
library as following.
import { HttpErrorResponse } from '@angular/common/http';
Now find the sample code to log error.
getFavoriteWriter() {
this.writerService.getFavoriteWriter().subscribe(
data => {
this.favWriter = data;
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
//A client-side or network error occurred.
console.log('An error occurred:', err.error.message);
} else {
//Backend returns unsuccessful response codes such as 404, 500 etc.
console.log('Backend returned status code: ', err.status);
console.log('Response body:', err.error);
}
}
);
}
RxJS retry() to Handle Error
Some errors can be handled by just retrying request such as if errors are transient and unlikely to repeat. For example if we have slow network error and our request could not become successful then there are the chances to make request successful if request is retried.
To retry request automatically RxJS provides retry()
operator that is called on Observable
. retry()
operator accepts number argument, suppose we pass argument as retry(3)
then the request will be retried for 3 times.retry()
is imported from RxJS as following.
import 'rxjs/add/operator/retry';
Find the sample example to use retry()
.
getFavoriteWriter() {
this.writerService.getFavoriteWriter().retry(3).subscribe(
data => {
this.favWriter = data;
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
console.log('An error occurred:', err.error.message);
} else {
console.log('Backend returned status code: ', err.status);
console.log('Response body:', err.error);
}
}
);
}
Angular In-Memory Web API to Test Application
To test application we need Web Service URL. Angular provides In-Memory Web API that will provide Web Service URL. We can configure URLs with dummy data using In-Memory Web API. Find the steps to use Angular In-Memory Web API.
1. Open the command prompt and navigate to the directory where package.json
resides and run following command.
npm i angular-in-memory-web-api@0.5.3 --save
2. Create a class that will implement InMemoryDbService
. Define createDb()
method with some dummy data.
test-data.ts
import { InMemoryDbService } from 'angular-in-memory-web-api';
export class TestData implements InMemoryDbService {
createDb() {
//JSON data
let bookDetails = [
{ id: '101', name: 'Angular 2 by Krishna', category: 'Angular', year: '2015' },
{ id: '102', name: 'AngularJS by Krishna', category: 'Angular', year: '2015' },
{ id: '103', name: 'Angular 2 by Vishnu', category: 'Angular', year: '2016' },
{ id: '104', name: 'Core Java by Vishnu', category: 'Java', year: '2016' },
{ id: '105', name: 'JSP & Servlet by Vishnu', category: 'Java', year: '2016' },
{ id: '106', name: 'JPA by Vishnu', category: 'Java', year: '2016' },
{ id: '107', name: 'Hibernate by Krishna', category: 'Hibernate', year: '2015' }
];
//JSON data
let writerDetails =
{
writerId: 11, writerName: 'Mahesh',
books: [
{ id: '103', name: 'Angular Tutorial', category: 'Angular', year: '2016' },
{ id: '104', name: 'Core Java Tutorial', category: 'Java', year: '2015' }
]
};
//Text data
let welcomeMsg = "Welcome to the Angular world!";
return { books: bookDetails, writer: writerDetails, message: welcomeMsg };
}
}
We will get following Web Service URLs.
/api/books
/api/writer
/api/message
3. Before using In-Memory Web API we need to import InMemoryWebApiModule
in application module and configure TestData
class as following.
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { TestData } from './test-data';
@NgModule({
imports: [
------
InMemoryWebApiModule.forRoot(TestData)
],
------
})
export class AppModule { }
Find the link for more information on In-Memory Web API.
Complete Example
Find the project structure.
my-app
|
|--src
| |
| |--app
| | |
| | |--book.ts
| | |--writer.ts
| | |--writer.service.ts
| | |--writer.component.ts
| | |--writer.component.html
| | |
| | |--test-data.ts
| | |
| | |--app.component.ts
| | |--app.module.ts
| |
| |--main.ts
| |--index.html
| |--styles.css
|
|--node_modules
|--package.json
Now find the complete code.
book.ts
export interface Book {
id: number;
name: string;
category: string;
year: string;
}
writer.ts
import { Book } from './book';
export interface Writer {
writerId: number;
writerName: string;
books: Book[];
}
writer.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { Book } from './book';
import { Writer } from './writer';
@Injectable()
export class WriterService {
constructor(private http: HttpClient) { }
textUrl = "/api/message";
getTextMsg(): Observable<string> {
return this.http.get(this.textUrl, {responseType: 'text'});
}
bookUrl = "/api/books";
getBooks(): Observable<Book[]> {
return this.http.get<Book[]>(this.bookUrl);
}
filterBooks(category: string, year: string): Observable<Book[]> {
let httpHeaders = new HttpHeaders()
.set('Accept', 'application/json');
return this.http.get<Book[]>(this.bookUrl + '?category=' + category + '&year=' + year, {
headers: httpHeaders,
responseType: 'json'
});
}
writerUrl = "/api/writer";
getWriterWithFavBooks(): Observable<any> {
return this.http.get(this.writerUrl, {responseType: 'json'});
}
getFavoriteWriter(): Observable<Writer> {
return this.http.get<Writer>(this.writerUrl, {responseType: 'json'});
}
getFullResponseForWriter(): Observable<HttpResponse<any>> {
return this.http.get(this.writerUrl, {
observe: 'response'
});
}
myUrl = "/api/invalid";
getDataForUrl(): Observable<any> {
return this.http.get(this.myUrl);
}
}
writer.component.ts
import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/retry';
import { HttpErrorResponse } from '@angular/common/http';
import { FormBuilder } from '@angular/forms';
import { WriterService } from './writer.service';
import { Book } from './book';
import { Writer } from './writer';
@Component({
selector: 'app-writer',
templateUrl: './writer.component.html'
})
export class WriterComponent implements OnInit {
obsTextMsg: Observable<string>
obsBooks: Observable<Book[]>
books: Book[];
favBooks: Book[];
favWriter: Writer;
writer: Writer;
categories = [
{category: 'Angular'},
{category: 'Hibernate'},
{category: 'Java'}
];
years = [
{year: '2015'},
{year: '2016'}
];
constructor(private writerService: WriterService,
private formBuilder:FormBuilder) { }
ngOnInit() {
this.getTextMsg();
this.getBooks();
this.getWriterWithFavBooks();
this.getFavoriteWriter();
this.getWriter();
this.getData();
}
bookForm = this.formBuilder.group({
category: '',
year: ''
});
onFormSubmit() {
let category = this.bookForm.get('category').value;
let year = this.bookForm.get('year').value;
this.filterBooks(category, year);
}
getTextMsg() {
this.obsTextMsg = this.writerService.getTextMsg();
this.writerService.getTextMsg().subscribe(
msg => console.log(msg)
);
}
getBooks() {
this.obsBooks = this.writerService.getBooks();
}
filterBooks(category: string, year: string) {
this.writerService.filterBooks(category, year)
.subscribe(data => this.books = data);
}
getWriterWithFavBooks() {
this.writerService.getWriterWithFavBooks().subscribe(
data => {
this.favBooks = data['books'];
}
);
}
getFavoriteWriter() {
this.writerService.getFavoriteWriter().retry(2).subscribe(
data => {
this.favWriter = data;
console.log(this.favWriter.books);
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
//A client-side or network error occurred.
console.log('An error occurred:', err.error.message);
} else {
//Backend returns unsuccessful response codes such as 404, 500 etc.
console.log('Backend returned status code: ', err.status);
console.log('Response body:', err.error);
}
}
);
}
getWriter() {
this.writerService.getFullResponseForWriter().subscribe(
res => {
this.writer = res.body;
console.log(this.writer.books);
console.log(res.headers.get('Content-Type'));
},
err => {
console.log(err);
}
);
}
getData() {
this.writerService.getDataForUrl().retry(3).subscribe(
res => {
console.log(res);
},
(err: HttpErrorResponse) => {
if (err.error instanceof Error) {
//A client-side or network error occurred.
console.log('An error occurred:', err.error.message);
} else {
//Backend returns unsuccessful response codes such as 404, 500 etc.
console.log('Backend returned status code: ', err.status);
console.log('Response body:', err.error);
}
}
);
}
}
writer.component.html
<h3 *ngIf="obsTextMsg | async as message"> {{ message }} </h3>
<h3>Book Details</h3>
<ul>
<li *ngFor="let book of obsBooks | async" >
Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}}, Year: {{book.year}}
</li>
</ul>
<h3>Filter Books</h3>
<form [formGroup]="bookForm" (ngSubmit)="onFormSubmit()">
Select Category:
<select formControlName="category">
<option *ngFor="let cat of categories" [ngValue]="cat.category">
{{ cat.category }}
</option>
</select>
Select Year:
<select formControlName="year">
<option *ngFor="let yr of years" [ngValue]="yr.year">
{{ yr.year }}
</option>
</select>
<button>SUBMIT</button>
</form>
Result:
<ul>
<li *ngFor="let book of books" >
Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}}, Year: {{book.year}}
</li>
</ul>
<h3>Favorite Books</h3>
<ul>
<li *ngFor="let book of favBooks" >
Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}}, Year: {{book.year}}
</li>
</ul>
<h3>Favorite Writer Details</h3>
<div *ngIf="favWriter">
Writer Id: <b>{{favWriter.writerId}}</b>, Writer Name: <b>{{favWriter.writerName}}</b>
<ul>
<li *ngFor="let book of favWriter.books" >
Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}}, Year: {{book.year}}
</li>
</ul>
</div>
<h3>Writer Details</h3>
<div *ngIf="writer">
Writer Id: <b>{{writer.writerId}}</b>, Writer Name: <b>{{writer.writerName}}</b>
<ul>
<li *ngFor="let book of writer.books" >
Id: {{book.id}}, Name: {{book.name}}, Category: {{book.category}}, Year: {{book.year}}
</li>
</ul>
</div>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-writer></app-writer>
`
})
export class AppComponent {
}
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { WriterComponent } from './writer.component';
import { WriterService } from './writer.service';
//For InMemory testing
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { TestData } from './test-data';
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
ReactiveFormsModule,
InMemoryWebApiModule.forRoot(TestData)
],
declarations: [
AppComponent,
WriterComponent
],
providers: [
WriterService
],
bootstrap: [
AppComponent
]
})
export class AppModule { }
Run Application
To run the application, find the steps.
1. Download source code using download link given below on this page.
2. Use downloaded src in your Angular CLI application. To install Angular CLI, find the link.
3. Install angular-in-memory-web-api@0.5.3
4. Run ng serve using command prompt.
5. Access the URL http://localhost:4200
Find the print screen of the output.
References
Không có nhận xét nào:
Đăng nhận xét