I'm trying to talk to a somewhat RESTful API from an Angular 2 frontend.
To remove some item from a collection, I need to send some other data in addition to the removée unique id(that can be appended to the url), namely an authentication token, some collection info and some ancilliary data.
The most straightforward way I've found to do so is putting the authentication token in the request Headers, and other data in the body.
However, the Http module of Angular 2 doesn't quite approve of a DELETE request with a body, and trying to make this request
let headers= new Headers();
headers.append('access-token', token);
let body= JSON.stringify({
target: targetId,
subset: "fruits",
reason: "rotten"
});
let options= new RequestOptions({headers:headers});
this.http.delete('http://testAPI:3000/stuff', body,options).subscribe((ok)=>{console.log(ok)}); <------line 67
gives this error
app/services/test.service.ts(67,4): error TS2346: Supplied parameters do not match any signature of call target.
Now, am I doing something wrong syntax-wise? I'm pretty sure a DELETE body is supported per RFC
Are there better ways to send that data?
Or should I just dump it in headers and call it a day?
Any insight on this conundrum would be appreciated
This question is related to
angular
rest
http-delete
In Angular Http 7, the DELETE method accepts as a second parameter options
object in which you provide the request parameters as params
object along with the headers
object. This is different than Angular6.
See example:
this.httpClient.delete('https://api-url', {
headers: {},
params: {
'param1': paramValue1,
'param2': paramValue2
}
});
deleteInsurance(insuranceId: any) {
const insuranceData = {
id : insuranceId
}
var reqHeader = new HttpHeaders({
"Content-Type": "application/json",
});
const httpOptions = {
headers: reqHeader,
body: insuranceData,
};
return this.http.delete<any>(this.url + "users/insurance", httpOptions);
}
Since the deprecation of RequestOptions, sending data as body in a DELETE request is not supported.
If you look at the definition of DELETE, it looks like this:
delete<T>(url: string, options?: {
headers?: HttpHeaders | {
[header: string]: string | string[];
};
observe?: 'body';
params?: HttpParams | {
[param: string]: string | string[];
};
reportProgress?: boolean;
responseType?: 'json';
withCredentials?: boolean;
}): Observable<T>;
You can send payload along with the DELETE request as part of the params in the options object as follows:
this.http.delete('http://testAPI:3000/stuff', { params: {
data: yourData
}).subscribe((data)=>.
{console.log(data)});
However, note that params only accept data as string or string[] so you will not be able to send your own interface data unless you stringify it.
Below is a relevant code example for Angular 4/5 with the new HttpClient.
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
public removeItem(item) {
let options = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
body: item,
};
return this._http
.delete('/api/menu-items', options)
.map((response: Response) => response)
.toPromise()
.catch(this.handleError);
}
If you use Angular 6 we can put body in http.request
method.
You can try this, for me it works.
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
constructor(
private http: HttpClient
) {
http.request('delete', url, {body: body}).subscribe();
}
}
The REST doesn't prevent body inclusion with DELETE request but it is better to use query string as it is most standarized (unless you need the data to be encrypted)
I got it to work with angular 2 by doing following:
let options:any = {}
option.header = new Headers({
'header_name':'value'
});
options.search = new URLSearchParams();
options.search.set("query_string_key", "query_string_value");
this.http.delete("/your/url", options).subscribe(...)
You are actually able to fool Angular2 HTTP
into sending a body
with a DELETE
by using the request
method. This is how:
let body = {
target: targetId,
subset: "fruits",
reason: "rotten"
};
let options = new RequestOptionsArgs({
body: body,
method: RequestMethod.Delete
});
this.http.request('http://testAPI:3000/stuff', options)
.subscribe((ok)=>{console.log(ok)});
Note, you will have to set the request method in the RequestOptionsArgs
and not in http.request
's alternative first parameter Request
. That for some reason yields the same result as using http.delete
I hope this helps and that I am not to late. I think the angular guys are wrong here to not allow a body to be passed with delete, even though it is discouraged.
Below is the relevant code example for Angular 2/4/5 projects:
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({
headers: headers,
body: {
id: 123
}
});
return this.http.delete("http//delete.example.com/delete", options)
.map((response: Response) => {
return response.json()
})
.catch(err => {
return err;
});
Notice that
body
is passed throughRequestOptions
Below is an example for Angular 6
deleteAccount(email) {
const header: HttpHeaders = new HttpHeaders()
.append('Content-Type', 'application/json; charset=UTF-8')
.append('Authorization', 'Bearer ' + sessionStorage.getItem('accessToken'));
const httpOptions = {
headers: header,
body: { Email: email }
};
return this.http.delete<any>(AppSettings.API_ENDPOINT + '/api/Account/DeleteAccount', httpOptions);
}
In Angular 5, I had to use the request method instead of delete to send a body. The documentation for the delete method does not include body, but it is included in the request method.
import { HttpClient } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
this.http.request('DELETE', url, {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
body: { foo: bar }
});
The http.delete(url, options)
does accept a body. You just need to put it within the options object.
http.delete('/api/something', new RequestOptions({
headers: headers,
body: anyObject
}))
Reference options interface:
https://angular.io/api/http/RequestOptions
UPDATE:
The above snippet only works for Angular 2.x, 4.x and 5.x.
For versions 6.x onwards, Angular offers 15 different overloads. Check all overloads here: https://angular.io/api/common/http/HttpClient#delete
Usage sample:
const options = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
body: {
id: 1,
name: 'test',
},
};
this.httpClient
.delete('http://localhost:8080/something', options)
.subscribe((s) => {
console.log(s);
});
Source: Stackoverflow.com