- Angular Tutorial
- Angular - Home
- Angular - Overview
- Angular - Features
- Angular - Advantages & Disadvantages
- Angular Basics
- Angular - Environment setup
- Angular - First Application
- Angular - MVC Architecture
- Angular Components
- Angular - Components
- Angular - Component Lifecycle
- Angular - View Encapsulation
- Angular - Emulated Encapsulation
- Angular - ShadowDom Encapsulation
- Angular - Component Interaction
- Angular - Using @Input Decorator
- Angular - Using @Output Decorator
- Angular - Using Local Variable
- Angular - Using @ViewChild Decorator
- Angular - Using Services
- Angular - Component Styles
- Angular - Nested Components
- Angular - Content projection
- Angular - Single-slot Content Projection
- Angular - Multi-slot Content Projection
- Angular - Conditional Content Projection
- Angular - Dynamic components
- Angular - Using NgComponentOutlet
- Angular - Using ViewContainerRef
- Angular - Elements
- Angular Templates
- Angular - Templates
- Angular - Template statements
- Angular - Template Variables
- Angular - SVG as Templates
- Angular Binding
- Angular - Data Binding
- Angular - Interpolation
- Angular - Event Binding
- Angular - Property Binding
- Angular - Attribute Binding
- Angular - Class Binding
- Angular - Style Binding
- Angular - Two-way Binding
- Angular Directives
- Angular - Directives
- Angular - Attribute Directives
- Angular - Structural Directives
- Angular - Custom Directives
- Angular Pipes
- Angular - Pipes
- Angular - Built-in Pipes
- Angular - Custom Pipes
- Angular Forms
- Angular - Forms
- Angular - Template Driven Forms
- Angular - Reactive Forms
- Angular - Form Validation
- Angular - Dynamic Forms
- Angular Dependency Injection
- Angular - Dependency Injection
- Angular - Injectable Service
- Angular Routing
- Angular - Routing
- Angular - Dynamic Routes
- Angular - Wildcard Routes
- Angular - Nested Routes
- Angular - Navigation
- Angular - Routing in SPA
- Angular - Custom Route Matches
- Angular - Router Reference
- Angular HTTP Client programming
- Angular - Services
- Angular - HTTP Client
- Angular - Express based REST API
- Angular - Request
- Angular - Request Response Workflow
- Angular - Response
- Angular - Express based Upload API
- Angular - GET
- Angular - POST
- Angular - PUT
- Angular - DELETE
- Angular - JSONP
- Angular - CRUD Operations Using HTTP
- Angular Modules
- Angular - Introduction to Modules
- Angular - Root Module
- Angular - Feature Module
- Angular - Sharing Module
- Angular - Routing Module
- Angular - NgModules
- Angular Animation
- Angular - Animations
- Angular Service Workers & PWA
- Angular - Service Workers & PWA
- Angular Testing
- Angular - Testing Overview
- Angular Design Patterns
- Angular - Design Patterns
- Angular - Lazy Loading
- Angular - Singleton Pattern
- Angular - Observer Pattern
- Angular Libraries
- Angular - Libraries
- Angular - Angular Material
- Angular - PrimeNG
- Angular - RxJS
- Angular Advanced
- Angular - Signals
- Angular - Authentication & Authorization
- Angular - Internationalization
- Angular - Standalone Component
- Angular - Accessibility
- Angular - Web Workers
- Angular - Server Side Rendering
- Angular - Ivy Compiler
- Angular - Building with Bazel
- Angular - Backward Compatibility
- Angular - Reactive Programming
- Angular Tools
- Angular - CLI
- Angular Material UI Elements
- Angular - Paginator
- Angular - Datepicker
- Angular - Select Drop-down
- Angular Miscellaneous
- Angular - Third Party Controls
- Angular - Configuration
- Angular - Displaying Data
- Angular - Decorators & Metadata
- Angular - Basic Example
- Angular - Error Handling
- Angular - Testing & Building a Project
- Angular - Lifecycle Hooks
- Angular - User Input
- Angular - What's New?
- Angular Useful Resources
- Angular - Quick Guide
- Angular - Useful Resources
- Angular - Discussion
Angular - Http Client
HTTP is an application layer protocol on the Internet. It stands for Hypertext Transfer Protocol and is the foundation of any data exchange on the web. It transmits hypertext requests and information between a server and a browser (client).
What is HTTP Client?
HTTP Client is a client-side programming that provides the HTTP server access to various resources and services. It allows the client (a browser or application) to send HTTP requests and receive responses from the server.
HTTP client programming is an important feature in every modern web application. Nowadays, many applications expose their functionality through REST APIs, which work over the HTTP protocol.
To support this, the Angular team offers extensive tools to enable HTTP communication with servers. Angular provides a module called HttpClientModule and a service called HttpClient to handle HTTP programming.
The following diagram provides a clear understanding of the HTTP Client, and the request and response mechanism −
Let us learn how to use the HttpClient service in this chapter. Developers should have a basic understanding of HTTP programming to understand the concepts discussed in this chapter.
Create a Server for Expense REST APIConfigure Http client
Let's learn how to configure the HttpClientservice. You need to import the HttpClient in App Config:
provideHttpClient(withInterceptorsFromDi())
app.config.ts
import { ApplicationConfig, provideBrowserGlobalErrorListeners } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [
provideBrowserGlobalErrorListeners(),
provideRouter(routes),
provideHttpClient(withInterceptorsFromDi())
]
};
Create expense service
Let us create a new service named ExpenseEntryin your ExpenseManagerapplication to interact withExpense REST API. ExpenseEntryService will get the latest expense entries, insert new expense entries, modify existing expense entries, and delete the unwanted expense entries.
Open the command prompt and go to the project root folder:
cd /go/to/expense-manager
Start the application by running the below command:
ng serve
Run the below command to generate an Angular service with the name ExpenseEntry:
ng g s expense-entry
This will create two Typescript files (expense entry service & its testing file) as specified below:
CREATE src/app/expense-entry.spec.ts (364 bytes) CREATE src/app/expense-entry.ts (141 bytes)
Run the below command to generate an Angular Interface with the name Expense:
ng g i expense CREATE src/app/expense.ts (141 bytes)
Now, open the Expense Interface (src/app/expense.ts) file.
export interface Expense {
id: number,
item: string,
amount: number,
category: string,
location: string,
spendOn: string,
createdOn: string
}
Now, open the ExpenseEntry Service (src/app/expense-entry.service.ts) file. import ExpenseEntry, throwError, and catchErrorfrom the rxjs library, and importHttpClient, HttpHeaders, and HttpErrorResponse from @angular/common/http package:
import { Injectable } from '@angular/core';
import { Expense } from './expense';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
Inject the HttpClient service into our service:
constructor(private httpClient : HttpClient) { }
Create a variable, expenseRestUrl to specify the Expense Rest API endpoints:
private expenseRestUrl = 'http://localhost:8000/api/expense';
Create a variable,httpOptionsto set the HTTP Header option. This will be used during the Http Rest API call by the AngularHttpClientservice:
private httpOptions = {
headers: new HttpHeaders( { 'Content-Type': 'application/json' })
};
The complete code is as follows:
expense-entry.ts
import { Injectable } from '@angular/core';
import { Expense } from './expense';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
@Injectable({
providedIn: 'root'
})
export class ExpenseEntry {
private expenseRestUrl = 'api/expense';
private httpOptions = {
headers: new HttpHeaders({'Content-Type': 'application/json'})
};
constructor(private httpClient : HttpClient) { }
}
HTTP GET
The HttpClient provides a get() method to fetch data from a web page. The main argument is the target web URL. Another optional argument is the option object with the below format −
{
headers?: HttpHeaders | {[header: string]: string | string[]},
observe?: 'body' | 'events' | 'response',
params?: HttpParams|{[param: string]: string | string[]},
reportProgress?: boolean,
responseType?: 'arraybuffer'|'blob'|'json'|'text',
withCredentials?: boolean,
}
Here,
headers: HTTP Headers of the request, either as string, an array of string, or an array of HttpHeaders.
- observe: Process the response and return the specific content of the response. Possible values are body, response, and events. The default option of the observer is the body.
- params: HTTP parameters of the request, either as string, array of string, or array of HttpParams.
- reportProgress: Whether to report the progress of the process or not (true or false).
- responseType: Refers to format of the response. Possible values are arraybuffer, blob, JSON, and text.
withCredentials: Whether the request has credentials or not (true or false).
Note: All options are optional, you can choose to use them or not.
The get() method returns the response of the request as Observable. The returned Observable emits the data when the response is received from the server.
The sample code to useget()method is as follows:
httpClient.get(url, options) .subscribe( (data) => console.log(data) );
Typed Response
Theget()method has an option to return observables, which emits a typed response as well. The sample code to get a typed response (ExpenseEntry) is as follows:
httpClient.get<T>(url, options) .subscribe( (data: T) => console.log(data) );
Handling errors
Error handling is one of the important aspects of HTTP programming. Encountering errors is one of the common scenarios in HTTP programming.
Errors in HTTP Programming can be categorized into two groups −
- Client-side issues can occur due to network failure, misconfiguration, etc. If a client-side error happens, then theget()method throwsan ErrorEventobject.
- Server-side issues can occur due to wrong URL, server unavailability, server programming errors, etc.
Let us write a simple error handling for our ExpenseEntry service.
private httpErrorHandler (error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.error("A client side error occurs. The error message is "
+ error.message);
} else {
console.error(
"An error happened in server. The HTTP status code is "
+ error.status + " and the error returned is " + error.message);
}
return throwError("Error occurred. Pleas try again");
}
The error function can be called in get() as specified below −
httpClient.get(url, options) .pipe(catchError(this.httpErrorHandler) .subscribe( (data) => console.log(data) )
Handle failed request
As we mentioned earlier, errors can happen, and one way is to handle them by implementing the error handling. Another option is to try for a certain number of times. If the request fails due to a network issue or the HTTP server is temporarily offline, the next request may succeed.
We can usethe rxjslibrary"retry"operator in this scenario as specified below :
httpClient.get(url, options)
.pipe(
retry(5),
catchError(this.httpErrorHandler))
.subscribe( (data) => console.log(data) )
Fetch expense entries
Let us do the actual coding to fetch the expenses from Expense Rest API in our ExpenseManager application.
Open the command prompt and go to the project root folder:
cd /go/to/expense-manager
Start the application by running the following command:
ng serve
Now, add the getExpenseEntries() and httpErrorHandler() methods in ExpenseEntryService (src/app/expense-entry.service.ts) service as follows:
getExpenseEntries() : Observable<Expense[]> {
return this.httpClient.get<Expense[]>(this.expenseRestUrl, this.httpOptions)
.pipe(retry(3),catchError(this.httpErrorHandler));
}
getExpenseEntry(id: number) : Observable<Expense> {
return this.httpClient.get<Expense>(this.expenseRestUrl + "/" + id, this.httpOptions)
.pipe(
retry(3),
catchError(this.httpErrorHandler)
);
}
private httpErrorHandler (error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.error("A client side error occurs. The error message is " + error.message);
} else {
console.error(
"An error happened in server. The HTTP status code is " +
error.status + " and the error returned is " + error.message);
}
return throwError("Error occurred. Pleas try again");
}
Here,
- getExpenseEntries() calls the get() method using expense end point and also configures the error handler. Also, it configures httpClient to try for maximum of 3 times in case of failure. Finally, it returns the response from server as typed (ExpenseEntry[]) Observable object.
- getExpenseEntry is similar to getExpenseEntries() except it passes the id of the ExpenseEntry object and gets ExpenseEntry Observable object.
expense-entry.ts
The complete coding of ExpenseEntry Service is as follows:
import { Injectable } from '@angular/core';
import { Observable, throwError } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';
import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http';
import { Expense } from './expense';
@Injectable({
providedIn: 'root'
})
export class ExpenseEntry {
private expenseRestUrl = 'http://localhost:8000/api/expense';
private httpOptions = {
headers: new HttpHeaders( { 'Content-Type': 'application/json' })
};
constructor(private httpClient : HttpClient) { }
getExpenseEntries() : Observable<Expense[]> {
return this.httpClient.get<Expense[]>(this.expenseRestUrl, this.httpOptions)
.pipe(
retry(3),
catchError(this.httpErrorHandler)
);
}
getExpenseEntry(id: number) : Observable<Expense> {
return this.httpClient.get<Expense> (this.expenseRestUrl + "/" + id, this.httpOptions)
.pipe(
retry(3),
catchError(this.httpErrorHandler)
);
}
private httpErrorHandler (error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
console.error("A client side error occurs. The error message is " + error.message);
} else {
console.error(
"An error happened in server. The HTTP status code is "
+ error.status + " and the error returned is " + error.message);
}
return throwError("Error occurred. Pleas try again");
}
}
Open theExpenseEntryList and go to the "src-entry-list-entry-list.ts" file and inject ExpenseEntry Service through the constructor as specified below:
constructor(private debugService: Debug, private restService : ExpenseEntry ) { }
Change thegetExpenseEntries()method, and call the "getExpenseEntries()" method from ExpenseEntry Service instead of returning the mock items:
getExpenseItems() {
this.restService.getExpenseEntries()
.subscribe( data =− this.expenseEntries = data );
}
The completeExpenseEntryListcodes are as follows −
expense-entry-list.ts
import { Component, OnInit } from '@angular/core';
import { Debug } from '../debug';
import { Expense } from '../expense';
import { ExpenseEntry } from '../expense-entry';
@Component({
selector: 'app-expense-entry-list',
templateUrl: './expense-entry-list.html',
styleUrls: ['./expense-entry-list.css'],
providers: [Debug, ExpenseEntry]
})
export class ExpenseEntryList implements OnInit {
title: string = '';
expenseEntries: Expense[] = [];
constructor(
private debugService: Debug,
private restService : ExpenseEntry
) { }
ngOnInit() {
this.debugService.info("Expense Entry List component initialized");
this.title = "Expense Entry List";
this.getExpenseItems();
}
getExpenseItems() {
this.restService.getExpenseEntries()
.subscribe( data => this.expenseEntries = data );
}
}
Finally, check the application and you will see the below response:
HTTP POST
The HTTP POST is similar to HTTP GET except that the post request will send the necessary data as posted content along with the request. HTTP POST is used to insert new records into the system. HttpClientprovidesthe post()method, which is similar toget(), except it supports an extra argument to send the data to the server.
Let us add a new method, addExpenseEntry() in our ExpenseEntry Service to add new expense entry as mentioned below:
addExpenseEntry(expenseEntry: Expense): Observable<Expense> {
return this.httpClient.post<ExpenseEntry>(this.expenseRestUrl, expenseEntry, this.httpOptions)
.pipe(
retry(3),
catchError(this.httpErrorHandler)
);
}
HTTP PUT
The HTTP PUT is similar to HTTP POST requests. This is used to update existing records in the system. The HttpClient provides a put()method, which is similar topost().
Update expense entry
Let us add a new method, updateExpenseEntry() in our ExpenseEntry Service to update existing expense entry as mentioned below:
updateExpenseEntry(expenseEntry: Expense): Observable<Expense> {
return this.httpClient.put<Expense>(this.expenseRestUrl + "/" + expenseEntry.id, expenseEntry, this.httpOptions)
.pipe(
retry(3),
catchError(this.httpErrorHandler)
);
}
HTTP DELETE
The HTTP DELETE is similar to the HTTP GET request. It is used to delete entries in the system. The HttpClient provides a delete()method, which is similar toget().
Delete expense entry
Let us add a new method, deleteExpenseEntry() in our ExpenseEntry Service to delete existing expense entries as mentioned below:
deleteExpenseEntry(expenseEntry: Expense | number) : Observable<Expense> {
const id = typeof expenseEntry == 'number' ? expenseEntry : expenseEntry.id
const url = `${this.expenseRestUrl}/${id}`;
return this.httpClient.delete<Expense>(url, this.httpOptions)
.pipe(
retry(3),
catchError(this.httpErrorHandler)
);
}
Multiple Choice Questions (MCQ's):
Here we have mentioned a few MCQs to test your knowledge on the current concept:
Q 1 − What does HttpClient in Angular do?
Answer : C
Explanation:
In Angular, the HttpClient performs HTTP requests to communicate with backend services.
Q 2 − What does HttpClient return when making requests?
Answer : D
Explanation:
In Angular, the HttpClient returns an Observable, allowing for asynchronous data handling.
Q 3 − Which method is provided by HttpClient to make HTTP requests?
Answer : B
Explanation:
The get() method is one of the methods provided by HttpClient to make HTTP requests in Angular.