Call Delete Method from WebAPI


#1

Hi boys, I’m developing an app where I need call the delete method in a webapi. I try use httpcliente, as use post method, I try call delete method, but don’t work. Can somebody help me with a example. I’m using Ionic 3 with AngularJS 5.x.

Thank you.

Javier.


#2

What does that mean? What is happening or not?

What is your code?


#3

Good morning Sujan, and thank you for for time.

My code, where I do that tell, is the follow:

import { GlobalProvider } from ‘./…/global/global’;
import { HttpClient, HttpHeaders } from ‘@angular/common/http’;
import { Injectable } from ‘@angular/core’;

apiUrl: string;

constructor(public http: HttpClient, global: GlobalProvider) {
this.apiUrl = global.GetApiURL();

console.log('Hello PropertyProvider Provider');

}

unSetFavorite(customerId: number, propertyId: number){
let data = ({ userId: customerId, propertyId: propertyId });

let headers = new HttpHeaders();

headers.append('Content-Type', 'application/json');
headers.append('Access-Control-Allow-Origin', '*');
headers.append('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, DELETE, PUT');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Headers', 'X-Requested-With');

return new Promise((resolve, reject) => {
  **this.http.delete(this.apiUrl+'/favoriteproperty/0', JSON.stringify(data), {haders: headers })**
    .subscribe(res => {
      console.log(res);
    }, err => {
      console.log(err);
    });
});

}

And the error is:

Typescript Error
Expected 1-2 arguments, but got 3.
C:/baigungold/src/providers/property/property.ts
return new Promise((resolve, reject) => { this.http.delete(this.apiUrl+'/favoriteproperty/0', JSON.stringify(data), {haders: headers }).subscribe(res => {

#4

Please edit your post, it is not very readable at the moment.
Use the </> button above the input field to format your code, command line output or error message (select the text first, then click the button or wrap it in ``` manually). Check the preview if it looks better. This will make sure your text is readable and if it recognizes the programming language it also automatically adds code syntax highlighting. Thanks.


#5

The error message tells you exactly what your error is. Delete only takes 1 or 2 arguments (depending on if you need to send it options). It does not take 3. So…what’s the question?


#6

Thank you Rlouie, yes the error es very clear, but don’t understand how implement or use this function, because in other case, the error was that, Delete don’t is a function of http or Httpclient. In many post, I can read that the call to Delete method is by a request, but in these cases, don’t say how pass the json data.

I hope be clear.

Thank very much.

Javier.


#7

Right…because you don’t…that’s the whole point of the error message. All you have to do is read the docs, any tutorial, follow basic REST principals… https://angular.io/api/common/http/HttpClient#delete

DELETE calls don’t have json.


#8

Thank Rlouie, this document, I read, but my question or problem is, how pass the data in the json structure. Sorry, I don’t be annoying or idle.

Thank very mucho for your help.

Javier.


#9

I sorry, but now I do this. It, I taken from example in the web site that share with me RLouie.

  unSetFavorite(customerId: number, propertyId: number): Observable<any[]> {
    let data = ({ userId: customerId, propertyId: propertyId });

    let headers = new HttpHeaders();

    headers.append('Content-Type', 'application/json');
    headers.append('Access-Control-Allow-Origin', '*');
    headers.append('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, DELETE, PUT');
    headers.append('Accept', 'application/json');
    headers.append('Access-Control-Allow-Headers', 'X-Requested-With');

    return this.http.delete<data>(this.apiUrl+'/favoriteproperty/0/', headers).pipe(
        tap(ok => { console.log('The element was deleted'); }),
        catchError(console.log('Can delete the element')));
  }

And show:

TypeError: this.selector is not a function
    at CatchSubscriber.error (http://localhost:8100/build/vendor.js:133690:31)
    at DoSubscriber._error (http://localhost:8100/build/vendor.js:139664:30)
    at DoSubscriber.Subscriber.error (http://localhost:8100/build/vendor.js:35325:18)
    at MapSubscriber.Subscriber._error (http://localhost:8100/build/vendor.js:35351:26)
    at MapSubscriber.Subscriber.error (http://localhost:8100/build/vendor.js:35325:18)
    at FilterSubscriber.Subscriber._error (http://localhost:8100/build/vendor.js:35351:26)
    at FilterSubscriber.Subscriber.error (http://localhost:8100/build/vendor.js:35325:18)
    at MergeMapSubscriber.OuterSubscriber.notifyError (http://localhost:8100/build/vendor.js:56733:26)
    at InnerSubscriber._error (http://localhost:8100/build/vendor.js:116440:21)
    at InnerSubscriber.Subscriber.error (http://localhost:8100/build/vendor.js:35325:18)

#10

A rule I always try to follow is “never include even a single line in my code that I would not be able to explain why it is there and what it is doing”.

Try going through that exercise with each and every line of unSetFavorite, including the signature of the function itself. Remove every line you can’t completely explain to yourself and see what remains.


#11

Thank you rapropos, I followed your advice, and the erro was in other file. This I could solve, but the call to delete method don’t work. I think It is because the API is waiting a json, and I don’t know how send this information.


#12

OK, then, if you wouldn’t mind, please post what remains of unSetFavorite(), annotated with a comment for each line, explaining in your own words what that line is doing and why it is necessary.

I hope headers is completely gone, and I’m intrigued to see what the comment is for delete<data>, because generic type arguments are types, not objects.

As @rlouie said, it is extremely rare (and IMHO a very difficult design decision to defend) to have the body of a DELETE request be meaningful. In fact, the way I read the HTTP 1.1 spec, specifically sections 4.3 and 9.7, for request types with no defined semantics for what bodies mean (which describes DELETE), bodies should be ignored. All the information needed to identify the resource to be deleted must be present in the request URL itself, which is likely why HttpClient's delete method is written the way it is.

So, to summarize, if stuff in the body of a DELETE request is required to identify the resource to delete, then your server API is broken. Your first move should be to try to fix it, so that everything needed goes in the URL. If that’s not an option, you are going to have to resort to ugly chicanery. One possibility would be to eschew the delete method in favor of building your DELETE request using the generic request method instead. It’s documented in the same page @rlouie already provided.


#13

Dear partners, I could solve my problem. First to all, I can not explain each line, but I eliminated the json options in the Web API, and I put the data in the URL as indicated by the documentation sent by @rapropos. Then, I wrote the call to eliminate as it explains the documentation and the example sent by @rlouie.

Coming up next, I paste the code, how I solved it.

In the first lines, where we write the import sentences, I declare a constant:

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'text/html; charset=UTF-8',
                 'Access-Control-Allow-Origin': '*',
                 'Access-Control-Allow-Methods': 'DELETE, POST, GET, OPTIONS, PUT, HEAD',
                 'Access-Control-Allow-Headers': 'Content-Type' })};

Down, my method, where I delete the register. FavoriteProperty, is a class with the structure created for pass a personal type. In this case, FavoriteProperty, have 3 numeric fields as the table in the DB.

  unSetFavorite(customerId: number, propertyId: number): Observable<FavoriteProperty>{
    let UserIdAndPropertyId = customerId + ";" + propertyId;

    return this.http.delete<FavoriteProperty>(this.apiUrl+'/favoriteproperty/'+UserIdAndPropertyId, httpOptions).pipe(
        tap(_ => { console.log('Elimino la propiedad de favoritos'); }),
        catchError(err => of('No se pudo eliminar la propiedad de favoritos'))).subscribe(err => console.log(err));
  }

In other hand, this solution is partial, because, this setting for CORS, work only in IE, because when I launch ionic serve, in Chrome, don’t work, because the WebAPI understand the method received as OPTIONS, and not as DELETE.

I hope be clear.

Regards, and thank very much.

Javier.