101

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

Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219
TriTap
  • 1,131
  • 2
  • 7
  • 9
  • 1
    use POST and rename wording of delete to findAndDelete to make sense. – YOU Aug 08 '16 at 01:43
  • @YOU Yes I can, but shouldn't I try to keep destructive actions distinct from non-destructive ones right at the request type level? – TriTap Aug 08 '16 at 10:11
  • then you will have to put it in querystring, but normally you put id of what you want yo delete in url, and authentication bearer in ajax header to send delete request. – YOU Aug 08 '16 at 10:21
  • After a couple of hours searching a solution and receiving a lot of errors, I finally used POST method and now all works. – Yamashiro Rion Feb 08 '19 at 12:58

14 Answers14

219

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);
  });
n4nd0_o
  • 2,929
  • 1
  • 15
  • 9
28

If you use Angular 6 we can put body in http.request method.

Reference from github

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();
  }
}
Druta Ruslan
  • 7,171
  • 2
  • 28
  • 38
22

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, HttpHeaders } from '@angular/common/http';

this.http.request('DELETE', url, {
  headers: new HttpHeaders({
    'Content-Type': 'application/json',
  }),
  body: { foo: bar }
});
avi12
  • 2,000
  • 5
  • 24
  • 41
Jeff Cross
  • 221
  • 2
  • 3
  • If I try this method the Request Method contains OPTIONS instead of DELETE. Are you sure this is still working? – Jochen Apr 05 '18 at 10:21
  • @Jochen I am pretty sure this works for me and sends DELETE request in Angular 5 – Dominik Szymański Apr 18 '18 at 18:21
  • The problem has been found, it was the server that didn't answer with the correct OPTIONS and thus a DELETE was never send by the client because of that. – Jochen Apr 20 '18 at 06:17
19

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.

Hampus
  • 2,769
  • 1
  • 22
  • 38
  • I realize to late that @n4nd0_o's does the same thing but still using the original delete method. I'll leave this answer anyhow for an alternative solution. – Hampus Dec 02 '16 at 10:27
  • Yes @Hampus, we essentially provide the same answer. Yours is a bit more "verbose", nevertheless, the same solution :D – n4nd0_o Mar 08 '17 at 04:59
12

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);
  }
9

For angular 10, you can use also the generic request format and the DELETE method:

http.request('DELETE',  path, {
            body:body,
            headers: httpHeaders,
            params: ((params != null) ? params : new HttpParams())
        })
justCurious
  • 720
  • 7
  • 13
7

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);
        }
unknow27
  • 81
  • 1
  • 2
5

In Angular 13 this works well for me:

const options = {
   headers: this._headers,
   body: JSON.stringify(user)
};

return this._http.delete<DeleteVirtualAssistantResult>(`${this._apiUrl}/users`, options);
O.MeeKoh
  • 1,976
  • 3
  • 24
  • 53
1

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(...)
mbryja
  • 61
  • 1
  • 8
0

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 through RequestOptions

Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219
0

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
    }
});
Tihomir Mihaylov
  • 805
  • 7
  • 18
0
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);
    }
Sandeep Patel
  • 2,069
  • 2
  • 14
  • 20
-1

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.

  • The httpClient no longer offers the interface RequestOptions, but it provides several overloads and the overloads allow body as part of the request options. https://angular.io/api/common/http/HttpClient#delete i.e.Overload #15 – n4nd0_o Jul 13 '21 at 22:32
-12

Definition in http.js from the @angular/http:

delete(url, options)

The request doesn't accept a body so it seem your only option is to but your data in the URI.

I found another topic with references to correspond RFC, among other things: How to pass data in the ajax DELETE request other than headers

Community
  • 1
  • 1
AndreasV
  • 234
  • 1
  • 6
  • 1
    Is there a open issue on github for this topic? I think a optional body parameter be should definitely added. – Rose Nettoyeur Oct 01 '16 at 11:56
  • 32
    The two other answers prove this answer wrong and it shouldn't be the accepted answer. – Hampus Dec 02 '16 at 10:30
  • 1
    The provided link for this answer points to jquery ajax delete, not Angular 2 as specified on the question. This shouldn't be the accepted answer. – n4nd0_o Mar 08 '17 at 04:58
  • 1
    This answer shouldn't be downvoted, the RFC says that DELETE method does not support request body. So even though there may be workarounds to put it there, it's technically a hack. – LachoTomov Nov 01 '20 at 17:47
  • for people in 2021, unfortunately, this is the right answer. delete shouldn't support request body at all. +1 – minigeek Sep 24 '21 at 12:54