mgonto / restangular

AngularJS service to handle Rest API Restful Resources properly and easily
MIT License
7.87k stars 840 forks source link

Restangular sends empty {} request payload when removing object #78

Closed gryphon closed 11 years ago

gryphon commented 11 years ago

Rails application crashes with message "The document "{}" does not have a valid root" when making simple object remove. Seems to be caused by {}:none request params which should not be included into DELETE request.

mgonto commented 11 years ago

It's sending an empty request.

I'll send nothing. Thanks for the report.

kpgarrod commented 11 years ago

I am experiencing this same problem. Is there a workaround please? I really like the look of this library and am trying to test it, but this problem is a show-stopper.

I noticed that this error is coming from REXML. Is the content type json? Can I set the content type to json?

See: http://stackoverflow.com/questions/6106556/rails-throws-rexmlparseexception-does-not-have-a-valid-root-exception

mgonto commented 11 years ago

Hey,

I'm actually sending content type as JSon in both request and response.

Anyway, I've just pushed the fix, but I haven't tagged yet. I'll be tagging tomorrow.

Get the version from https://raw.github.com/mgonto/restangular/master/dist/restangular.js

Thanks!!!

gryphon commented 11 years ago

it seems that now restangular sends object ID as a param: "The document "{\"id\":23}" does not have a valid root" This is also not a correct behaviour for DELETE requests for rails apps

mgonto commented 11 years ago

Can you please try the following?

Add to your config:

RestangularProvider.setRequestInterceptor(function(elem, operation) {
  if (operation === "remove") {
     return undefined;
  } 
  return elem;
})

This way, you'll intercept whatever is being sent in remove and just send "undefined"

mgonto commented 11 years ago

Because I don't really want to remove this object being sent 100% from every DELETE request, as in other frameworks, it's needed.

But, I think that if you just make your request interceptor return undefined for your rails app, it'll work :). The advantage of having this configurable. Please let me know if this works out. I think it's the best solution :)

gryphon commented 11 years ago

This works! Thanks! In this case it is very important to include this fix to docs, lots of people are using rails..

mgonto commented 11 years ago

No problem :).

I think this makes more sense. If you need to send nothing, you can do it in your configuration, so that you can choose what's sent.

Also, for the rest of Rails methods, you're going to send a "root" object I think. So, you either change that configuration in your application.rb to accept without roots (I like it more that way), or you can actually add the root in this same requestInterceptor :)

I'm glad it helps :)

Closing now!

herval commented 11 years ago

Just a quick heads up: the code above didn't work for me - the operation is being sent as "delete", not remove. Therefore, this works:

RestangularProvider.setRequestInterceptor(function(elem, operation) { if (operation === "delete") { return undefined; } return elem; })

j-walker23 commented 10 years ago

Hey, i just started seeing this again, very weird i have other versions that are working. But my code is different as well. I set element to undefined. Could this be a "this" binding issue if i am doing something wierd? I also tried doing a Restangular.copy before the remove. I checked element, it is undefined but the body persists. I am on the latest version of Restangular. Is there anything else you know that i could try?

    Restangular.setFullRequestInterceptor(function (element, operation, route, url, headers, params) {

        if (operation == 'remove')
            element = undefined;

        return {
            headers: headers,
            params: params,
            element: element,
            httpConfig: {}
        };
    });
mgonto commented 10 years ago

Hey,

Try setting null instead of undefined. I think maybe undefined has stopped working since new version with multiple interceptors.

Thanks

j-walker23 commented 10 years ago

You are the man, thank you!

petehamilton commented 10 years ago

I just had exactly the same issue but switching undefined to null as above fixed it for me (I'm using a Rails API backend).

For reference:

Restangular.setFullRequestInterceptor(function (element, operation, route, url, headers, params) {
    if (operation == 'remove') {
      element = null;
    }

    return {
      headers: headers,
      params: params,
      element: element,
      httpConfig: {}
    };
});
KKrisu commented 10 years ago

This setting is also needed for Google App Engine backend APIs

j-walker23 commented 10 years ago

All of app engine. The weird thing is with the app engine dev server the delete body doesn't matter, just when you deploy does it hurt you!

KKrisu commented 10 years ago

@j-walker23 I experienced the same confusion. Unpleasant surprise when you deploy :/

JonCognioDigital commented 10 years ago

This setting is also needed when testing with Mockable.io. Caused a massive headache but luckily I found this thread.

Would it not be possible to include this as a config flag?

netes commented 9 years ago

Just for the record - setFullRequestInterceptor is deprecated, use addFullRequestInterceptor instead.

Ahmedmousa20 commented 1 year ago

Where should I put this Code?

RestangularProvider.setRequestInterceptor(function(elem, operation) { if (operation === "remove") { return undefined; } return elem; })