Angular is a popular front-end framework made by Google. Like other popular front-end frameworks, it uses a component-based architecture to structure apps.
In this article, we’ll look at how to make PUT and DELETE requests with the Angular HTTP Client and using HTTP interceptors.
Making a DELETE Request
We can use the delete
method to make a DELETE request by passing in the request URL as the first argument and an request options object as the 2nd argument
For example, we can use it as follows:
app.component.ts
:
import { Component } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.css"]
})
export class AppComponent {
constructor(private http: HttpClient) { } ngOnInit() {
this.getPost();
}
getPost() {
const httpOptions = {
headers: new HttpHeaders({
"Content-Type": "application/json"
})
};
this.http
.delete("https://jsonplaceholder.typicode.com/posts/1", httpOptions)
.subscribe(res => console.log(res));
}
}
In the code above, we call the delete
method with the URL and httpOptions
.
Then we call subscribe
to initiate the request. The subscribe
callback’s parameter has the response content.
Making a PUT Request
A PUT request can be made with the put
method. It’s similar to the post
method except it makes a PUT request.
The first argument is the URL, the 2nd is the request body, and the 3rd argument is the request options object.
For example, we can write the following:
app.component.ts
:
import { Component } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Post } from "./post";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls:["./app.component.css"]
})
export class AppComponent {
constructor(private http: HttpClient) {}
ngOnInit() {
this.addPost();
}
addPost() {
const body = {
userId: 1,
title: "title",
body: "body"
};
const httpOptions = {
headers: new HttpHeaders({
"Content-Type": "application/json"
})
};
this.http
.put<Post>(
"https://jsonplaceholder.typicode.com/posts/",
body,
httpOptions
)
.subscribe(res => console.log(res));
}
}
HTTP Interceptors
We can create and use HTTP interceptors to inspect and transform HTTP requests from our app to the server.
They can also be used to inspect and transform the server’s response on their way back to the app.
Multiple interceptors form a forward and backward chain of request/response handlers.
We can create and use our interceptor as follows:
http-req-interceptor.ts
:
import { Injectable } from "@angular/core";
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from "@angular/common/http";
import { Observable } from "rxjs";
@Injectable()
export class HttpReqInterceptor implements HttpInterceptor {
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return next.handle(req);
}
}
app.module.ts
:
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { HttpClientModule, HTTP_INTERCEPTORS } from "@angular/common/http";
import { AppComponent } from "./app.component";
import { HttpReqInterceptor } from "./http-req-inteceptor";
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, HttpClientModule],
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: HttpReqInterceptor, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule {}
In the code above, we created the HttpReqInterceptor
class that extends the HttpInterceptor
interface.
To implement the interface, we implement the intercept
method which returns the observable returned by next.handle
.
Then we can use it by adding the following:
{ provide: HTTP_INTERCEPTORS, useClass: HttpReqInterceptor, multi: true }
to the providers
array in AppModule
.
Interceptor Order
If we have interceptors A, B, and C provided in that order, then if we make an HTTP request, A runs, then B, then C.
When our app receives a response, it’ll run C first, then B, then A.
intercept
and handle
return HttpEvent<any>
instead of HttpResponse<any>
.
This is because interceptors examine and modify the response from next.handle
.
Immutability
HttpRequest
and HttpResponse
instance properties are readonly
, which makes them immutable.
This is good because requests may be retried several times. We don’t want the retry request to be modified before it’s retried.
Therefore, if we want to change the request, we have to clone it and then return next.handle
with the cloned request passed in as follows:
http-req-inteceptor.ts
:
import { Injectable } from "@angular/core";
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from "@angular/common/http";import { Observable } from "rxjs";
@Injectable()
export class HttpReqInterceptor implements HttpInterceptor {
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const secureReq = req.clone({
url: req.url.replace("http://", "https://")
});
return next.handle(secureReq);
}
}
In the code above, we modified all request URLs that started with http
to start with https
.
Modifying the Request Body
We can modify the request body as follows before sending it to the server:
http-req-interceptor.ts
:
import { Injectable } from "@angular/core";
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest
} from "@angular/common/http";import { Observable } from "rxjs";
@Injectable()
export class HttpReqInterceptor implements HttpInterceptor {
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const body = req.body;
const newBody = { ...body, title: body.name.trim() };
const newReq = req.clone({ body: newBody });
return next.handle(newReq);
}
}
In the code above, we copied the request body with:
const body = req.body;
const newBody = { ...body, title: body.name.trim() };
Then we set the body of the request to the newBody
by writing:
const newReq = req.clone({ body: newBody });
In the end, we returned the request observable.
We set the body to an empty object undefined
or null
to clear the request body in the example above.
Conclusion
We can make PUT and DELETE requests by calling the put
and delete
methods.
put
takes the URL as the first argument, the request body as the 2nd argument, and the request options object as the last argument.
delete
takes the URL as the first argument, and the request options object as the last argument.
To transform requests before sending it, we can create and user HTTP interceptors.
They can be chained and called in the same order they’re provided for making requests, and the reverse order when receiving responses.