
- 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 - Component Interaction
- Angular - Component Styles
- Angular - Nested Components
- Angular - Content projection
- Angular - Dynamic components
- 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 - Request
- Angular - Response
- 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 DELETE Request
The HTTP DELETE
The HTTP standard verb DELETE can be used in the HTTP protocol to request the deletion of a specific resource (data) on the server. The purpose of the DELETE method is to ask the server to remove a particular piece of data.
In Angular, the HttpClient service class provides a delete() method to delete data on the server. Let's learn more about this method, including its signature, various options, real-time usage, etc.
Signature of the delete() Method
Following is the signature (different from syntax) of the HttpClient delete() method −
delete<T>(url: string, options?: Object): Observable<T>
Here,
- URL − The URL to which the delete request is sent.
- options − An object containing HTTP options such as headers, query parameters, etc.
- Observable<T> − The return type, where 'T' represents the expected response type.
Options
Following is a list of the available options −
observe
The observe specifies which part of the response has to be observed during the server communication. Based on the observe option, either the full or part of the response will be returned as Observable. The possible values are body, events, and response.
body: Retrieves only the body content of the response from the HTTP request as Observable<R>, where R is based on the responseType option and the requested type (e.g., Expense) of data.
this.http.delete<Expense>(<url>, { 'observe': 'body', 'responseType' : 'json' })
Here,
- JSON is the format used to interprets the response body
- Expense is the requested type used to format the response body and returns as Observable<Expense>.
events: Retrieves the events fired in a response stream along with the corresponding response body as Observable<HttpEvent><R>>, where R is based on the responseType option and the requested type (e.g., Expense) of data.
this.http.delete<Expense>(<url>, { 'observe': 'events', 'responseType' : 'json' })
Here,
- JSON is the format used to interprets the response body.
- Expense is the requested type used to format the response body and returns Observable<HttpEvent<Expense>>.
response: It is used to retrieve the complete response from the HTTP request as Observable<HttpResponse<R>>, where R is based on the responseType option (which we will check in the next section) and the requested type (e.g., Expense) of data. The purpose of the HttpResponse class is to represent the complete HTTP response from the server.
this.http.delete<Expense>(<url>, { 'observe': 'response', 'responseType' : 'json' })
Here,
- JSON is the format used to interprets the response body.
- Expense is the requested type used to format the response body and returns Observable<HttpResponse<Expense>>.
responseType
The responseType is used to interpret the response body. It can have four possible values as shown below −
- arraybuffer
- blob
- text
- json
Let's understand the above options one by one:
arraybuffer: Interprets the response body as a generic raw binary data buffer and returns Observable. It can be used to stream audio/video content.
this.http.delete(<url>, { 'observe': 'body', 'responseType' : 'arraybuffer' })
blob: Interprets the response body as the binary format and returns Observable<blob>. It can be used to download large files.
this.http.delete(<url>, { 'observe': 'body', 'responseType' : 'blob' })
text: Interprets the response body as plain text format and returns Observable<String>. It can be used to represent text-based data.
this.http.delete(<url>, { 'observe': 'body', 'responseType' : 'json' })
JSON: Interprets the response body as JSON format and returns Observable<R>, where R is the requested type (e.g., Expense) of data. It can be used to represent the result in JSON format.
this.http.delete<Expense>(<url>, { 'observe': 'body', 'responseType' : 'json' })
Based on the observe and responseType, HttpClient returns Observable with a different type variable. Let's check a few combinations of observe and responseType to better understand this concept.
- observe => body and responseType => JSON
Returns the Observable. R represents the type variable.
- observe => response and responseType => JSON
Returns the Observable<HttpResponse>. R represents the type variable and encodes response body.
- observe => events and responseType => JSON
Returns the Observable<HttpEvent>. R represents the type variable and encodes the response body.
- observe => events and responseType => arraybuffer
Returns the Observable<HttpEvent>. The response body is encoded as ArrayBuffer.
- observe => response and responseType => blob
Returns the Observable<HttpEvent>. The Response body is encoded as ArrayBuffer.
- observe => response and responseType => text
Returns the Observable<HttpResponse>. The Response body is encoded as ArrayBuffer.
We can combine observe and responseType to create many more combinations as necessary.
headers
Theheadersspecify the HTTP headers. It can include a standard HTTP header as a key/value pair or can encode the data in the HttpHeaders class. A sample header as a key/value pair is as follows:
{ 'Content-type': 'application/json' }
It specifies that the request content type is JSON. We can also use the HttpHeaders class provided by angular to create HTTP headers. A sample set of header information using HttpHeaders is as follows −
// create header using `HttpHeaders` const headers = new HttpHeaders().set('content-type', 'application/json') .set('Access-Control-Allow-Origin', '*'); this.http.delete<Expense>(<url>, { 'observe': 'body', 'responseType' : 'json', headers: headers })
params
Theparamsrepresent the serialized request parameter in application/x-www-form-urlencoded format. It can include params as a key/value pair or can encode the data in the HttpParams class. A sample parameter as a key/value pair is as follows:
{ 'name': 'john' }
It specifies that the request param key is the name, and its value is john. We can also use the HttpParams class provided by angular to create parameters. A sample set of parameters using HttpParams is as follows −
// create parameters using `HttpParams` const params = new HttpParams().set('name', 'john').set('age', 25) .set('active', true; this.http.delete<Expense>(<url>, { 'observe': 'body', 'responseType' : 'json', params: params })
context
Thecontextsends arbitrary values as key/value pairs with type safety and without key conflict. It is used as a source of information for interceptors acting as middle-ware between client and server. Angular provides a special class, HttpContext to encode the context information. A sample context is as follows:
// create a key using HttpContextToken export const IS_AUTH_ENABLED = new HttpContextToken<boolean>(() => false); // set data for the context let authContext = new HttpContext().set(IS_AUTH_ENABLED, true) this.http.request<Expense>('GET', <url>, { 'observe': 'body', 'responseType' : 'json', context: authContext })
Here,
- HttpContextToken is used to create the key along with the value type.
- IS_AUTH_ENABLED is the key, and its type is boolean.
reportProgress
The reportProgress is used to specify whether to send back the progress of the request (communication) from the server. It can be used to show the progress of large file uploads through web API:
this.http.delete<Expense>(<url>, { 'observe': 'events', 'responseType' : 'json', reportProgress: true })
withCredentials
The withCredentials is used to specify whether the request should be sent with outgoing credentials (cookies). It accepts the boolean value:
this.http.delete<Expense>(<url>, { 'observe': 'body', 'responseType' : 'json', withCredentials: true })
transferCache
ThetransferCache specifies whether the request should be cached. It accepts the boolean value or HttpTransferCacheOptions value. HttpTransferCacheOptions encode dynamic logic to filter requests to be cached based on a custom filter function and override default cache behavior:
this.http.delete<Expense>(<url>, { 'observe': 'body', 'responseType' : 'json', transferCache: true })
Working Example
To work out the HTTP client-server communication, we need to set up a web application and expose a set of web API. The web API can be requested from the client. Let us create a sample server application, Expense API App to provide CRUD REST API (mainlyDELETEmethod) for expenses −
Step 1: Go to your favorite workspace as shown below −
cd /go/to/your/favorite/workspace
Step 2: Create a new folder, expense-rest-api, and move into the folder −
mkdir expense-rest-api && cd expense-rest-api
Step 3: Create a new application using the init sub-command provided by the npm command as shown below −
npm init
Once you run the above command, it will ask a few questions and answer all of them with default answers.
Step 4: Install express and cors packages to create node-based web applications −
npm install express cors --save
Step 5: Install SQLite package to store the expenses in the SQLite-based database −
npm install sqlite3 --save
Step 6: Create a new file with the name sqlitedb.js, and add the below code to initialize the database with expense table and sample expense entries. An expense table will be used to store the expense item −
var sqlite3 = require('sqlite3').verbose() const DBSOURCE = "expensedb.sqlite" let db = new sqlite3.Database(DBSOURCE, (err) => { if (err) { console.error(err.message) throw err }else{ console.log('Connected to the SQLite database.') db.run(`CREATE TABLE IF NOT EXISTS expense ( id INTEGER PRIMARY KEY AUTOINCREMENT, item text, amount real, category text, location text, spendOn text, createdOn text )`, (err) => { if (err) { console.log(err); }else{ var insert = 'INSERT INTO expense (item, amount, category, location, spendOn, createdOn) VALUES (?,?,?,?,?,?)' db.run(insert, ['Pizza', 10, 'Food', 'KFC', '2020-05-26 10:10', '2020-05-26 10:10']) db.run(insert, ['Pizza', 9, 'Food', 'Mcdonald', '2020-05-28 11:10', '2020-05-28 11:10']) db.run(insert, ['Pizza', 12, 'Food', 'Mcdonald', '2020-05-29 09:22', '2020-05-29 09:22']) db.run(insert, ['Pizza', 15, 'Food', 'KFC', '2020-06-06 16:18', '2020-06-06 16:18']) db.run(insert, ['Pizza', 14, 'Food', 'Mcdonald', '2020-06-01 18:14', '2020-05-01 18:14']) } } ); } }); module.exports = db
Step 7: Open the index.js (if not found, create it manually) and place the below code −
var express = require("express") var cors = require('cors') var db = require("./sqlitedb.js") var app = express() app.use(cors()); var bodyParser = require("body-parser"); app.use(express.urlencoded({ extended: true })); app.use(express.json()); var HTTP_PORT = 8000 app.listen(HTTP_PORT, () => { console.log("Server running on port %PORT%".replace("%PORT%", HTTP_PORT)) }); app.get("/", (req, res, next) => { res.json({ "message": "Ok" }) }); app.get("/api/expense", (req, res, next) => { var sql = "select * from expense" var params = [] db.all(sql, params, (err, rows) => { if (err) { res.status(400).json({ "error": err.message }); return; } res.json(rows) }); }); app.get("/api/expense/:id", (req, res, next) => { var sql = "select * from expense where id = ?" var params = [req.params.id] db.get(sql, params, (err, row) => { if (err) { res.status(400).json({ "error": err.message }); return; } res.json(row) }); }); app.use(function (req, res) { res.status(404); });
Here, the code will create six below-mentioned REST API endpoints:
- /endpoint returns an "OK" message to make sure the application is working fine.
- /api/expense endpoint returns all expense items available in the database.
- /api/expense/:id endpoint returns the expense entry based on the expense entry id.
- /api/expense/:id endpoint with delete verb will delete the expense entry based on the expense entry id.
Step 8: Run the application using the below command −
node index.js
Step 9: To test the application, open your friendly browser (chrome) and go to http://localhost:8000/. It should return the below message if the application is working fine −
{ "message": "Ok" }
Angular Sample Application
Let us create an angular application to delete an existing expense on the server using the HttpClient service class:
Step 1: Create a new angular application by running ng new command as shown below −
ng new my-http-app
Enable angular routing and CSS as shown below −
? Would you like to add Angular routing? Yes ? Which stylesheet format would you like to use? CSS
Step 2: Enable HTTP communication in the application by importing HttpClientModule in the component configuration file (app.component.ts) as per the latest version −
import { Component } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterOutlet } from '@angular/router'; import { HttpClientModule } from '@angular/common/http'; @Component({ selector: 'app-root', standalone: true, imports: [CommonModule, RouterOutlet, HttpClientModule], templateUrl: './app.component.html', styleUrl: './app.component.css' }) export class AppComponent { title = 'my-http-app'; }
Here,
- Import the HttpClientModule from the @angular/common/http module.
- Add the HttpClientModule into the imports array section of the @Component configuration.
Step 3: Create a new interface, Expense to represent our expense item −
interface Expense { id?: Number, item: String, amount: Number, category: String, location: String, spendOn: Date } export default Expense;
Here,
- Anidis set as an optional property.
Step 4: Create a new component, ListExpenses to show the expense items from the server −
ng generate component ListExpenses
It will create the component as shown below −
CREATE src/app/list-expenses/list-expenses.component.css (0 bytes) CREATE src/app/list-expenses/list-expenses.component.html (28 bytes) CREATE src/app/list-expenses/list-expenses.component.spec.ts (602 bytes) CREATE src/app/list-expenses/list-expenses.component.ts (229 bytes)
Step 5: Include our new component into the App root component view, app.component.html as shown below −
<app-list-expenses></app-list-expenses> <router-outlet></router-outlet>
Step 6: Inject the HttpClient into the ListExpenses component through the constructor as shown below −
import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-list-expenses', templateUrl: './list-expenses.component.html', styleUrls: ['./list-expenses.component.css'] }) export class ListExpensesComponent { constructor(private http: HttpClient) { } }
Step 7: Implement the OnInit life cycle hook to request the server for expenses after the initialization of the ListExpenses component −
export class ListExpensesComponent implements OnInit{ constructor(private http: HttpClient) { } ngOnInit(): void { } }
Step 8: Create a local variable, expenses to hold our expenses from the server −
export class ListExpensesComponent implements OnInit{ expenses: Expense[] = []; constructor(private http: HttpClient) { } ngOnInit(): void { } }
Step 9: Create a local variable, newexpense to hold the new expense created in the server −
export class ListExpensesComponent implements OnInit{ expenses: Expense[] = []; newexpense: Expense | null = null; constructor(private http: HttpClient) { } ngOnInit(): void { } }
Step 10: Call the get method of this.http (HttpClient instance) object by passing the list expenses URL and options and getting the expense object from the server. Then, set the expenses into our local variable, expenses −
export class ListExpensesComponent implements OnInit { expenses: Expense[] = []; newexpense: Expense | null = null; constructor(private http: HttpClient) { } ngOnInit(): void { this.http.get<Expense[]>('http://localhost:8000/api/expense', { 'observe': 'body', 'responseType': 'json' }).subscribe( data => { this.expenses = data as Expense[] console.log(this.expenses) }) } }
Here,
- Sets the Expense[] as the type of the object returned by the server. The server will send the array of expense objects along with a new expense object in its body in the JSON format.
- Subscribed to the request (this.http.get) object. Then parsed the subscribed data as an array of expense objects, and set it to a local expense variable (this.expenses).
Step 11: Add a new delete method and call thedelete()method of this.http (HttpClient instance) object by passing the delete URL −
export class ListExpensesComponent implements OnInit { expenses: Expense[] = []; newexpense: Expense | null = null; constructor(private http: HttpClient) { } delete(id? : Number) : void { if (id) { this.http.delete<Expense>('http://localhost:8000/api/expense/' + id,{ 'observe': 'body', 'responseType': 'json' }).subscribe( data => { console.log(data) this.http.get<Expense[]>('http://localhost:8000/api/expense',{ 'observe': 'body', 'responseType': 'json' }).subscribe( data => { this.expenses = data as Expense[] console.log(this.expenses) }) }); } } ngOnInit(): void { this.http.get<Expense[]>('http://localhost:8000/api/expense',{ 'observe': 'body', 'responseType': 'json' }) .subscribe( data => { this.expenses = data as Expense[]; console.log(this.expenses); }) } }
Step 12: Next, get the expenses list object and render it in our component template page (list-expenses.component.html). Also, add an anchor tag for each expense and set the delete method by passing the corresponding expense ID −
<div><h3>Expenses</h3></div> <ul> <li *ngFor="let expense of expenses"> {{expense.item}} @ {{expense.location}} for {{expense.amount}} USD on {{expense.spendOn | date:'shortDate' }} <a href="delete(expense.id)">delete</a> </li> </ul>
Here,
- When the user clicks the delete link, it will call the delete expense endpoint and delete the expense from the server.
Step 13: The complete code of the ListExpensesComponent is as follows −
import { Component, OnInit } from '@angular/core'; import { HttpClient, HttpRequest, HttpResponse, HttpEvent, HttpParams } from '@angular/common/http'; import Expense from '../Expense'; @Component({ selector: 'app-list-expenses', templateUrl: './list-expenses.component.html', styleUrls: ['./list-expenses.component.css'] }) export class ListExpensesComponent implements OnInit { expenses: Expense[] = []; newexpense: Expense | null = null; constructor(private http: HttpClient) { } ngOnInit(): void { var spend_date = new Date(); spend_date.setDate(spend_date.getDate() - 1); this.newexpense = { 'item': 'new item ' + Math.floor(Math.random() * 10), 'amount': Math.floor(Math.random() * 100), 'category': 'Food', 'location': 'KFC', 'spendOn': spend_date } this.http.delete<Expense>('http://localhost:8000/api/expense/1', this.newexpense,{ 'observe': 'body', 'responseType': 'json' }).subscribe( data => { this.newexpense = data as Expense; console.log(data) }); this.http.get<Expense[]>('http://localhost:8000/api/expense',{ 'observe': 'body', 'responseType': 'json' }).subscribe( data => { this.expenses = data as Expense[] console.log(this.expenses) }); } }
Step 14: Finally, run the application using the below command −
ng serve
Step 15: Open the browser and navigate to http://localhost:4200/ URL and check the output −
Here, the output shows our expenses as a list of items except item 1.
Conclusion
Angular provides an easy way to send data to the server through the HttpClient object.delete()is a specific method used to send data to the server. We will learn more HTTP methods to target other HTTP verbs in the upcoming chapters.
Multiple Choice Questions (MCQ's):
Here we have mentioned a few MCQs to test your knowledge on the current concept:
Q 1 − What is the main purpose of the HTTP DELETE method in Angular?
A − To delete a resource on the server
B − To send data to the server to create or update a resource
Answer : A
Explanation:
The DELETE method is used to request the removal of a specific resource on the server.
Q 2 − Which option in HttpClient.delete() allows you to specify query parameters in the request?
Answer : C
Explanation:
The params option allows you to add query parameters to the request URL.
Q 3 − In the HttpClient.delete() method, what does the URL parameter represent?
A − The data to be sent to the server
B − The server address for the DELETE request
Answer : B
Explanation:
In the HttpClient.delete() method, the URL parameter represents the server address or endpoint to which the DELETE request will be sent in order to delete a specific resource.