itmammoth / rails_sortable

Easy drag & drop sorting with persisting the arranged order for rails
MIT License
142 stars 37 forks source link

sortable_controller#reorder is returning bad JSON #51

Closed per-d closed 4 years ago

per-d commented 4 years ago

I had a lot of problem whit this. In my app I have built a lot of code "around" ajax request, e.g. a function that always is called when a JQuery reports a failure from the ajax request. The problem was that the failure function is dependent on that context is set before the ajax request. I first didn't do that (it's done in a common "before ajax" function), and therefor I didn't see any error. I then implemented setting the context also for the sortable list, that is to have a "spinner icon" automatically fired from the ajax functions. Then I suddenly got these error messages. I thought it had to do with my "ajax" functions, and it took a long time till I found out that it's always considered as an error in JQueries functions. I just do this in the overloaded reload action to avoid this: render json: {}, status: 200

I'm using Rails 4.2 and JQuery-rails 4.0.5, that is old versions and perhaps this isn't an issue in newer versions.

itmammoth commented 4 years ago

Hi, I can't reproduce that. Can you push your app anywhere I can have a look at?

per-d commented 4 years ago

Hi. It's a business app and very big so I don't know if I can do that. But here is how to reproduce it. You can do it much simplier, I just copied some parts from the code. And some HTML tags, I don't use the final alert in the app.

// to catch failure event from JQuery
$(document)
  .ajaxError(ajaxDefaultFailure);

//--------------------------------------------

var ajaxDefaultFailure = function(event, xhr, options, thrownError) {
  requestOk = (xhr.status === 200);
  errorPre  = 'Server error\n';
  //...
  errorText =
    '<b>URL</b>:    ' + options.url + '\n' +
    '<b>data</b>:   ' + JSON.stringify(options.data) + '\n' +
    '<b>status</b>: ' + JSON.stringify([ xhr.status, xhr.statusText ]) + '\n';
  if (requestOk) {
    errorPre =
      '<b><i>Internal javascript error</b></i>: ' +
      JSON.stringify((typeof thrownError === "object") ?
        thrownError.toString() : thrownError) +
      '\n';
  }
  alert(errorText + '\n' + errorPre);
}
per-d commented 4 years ago

I think the reason for the "error" is that reorder just responds with an empty string and the ajax request expects a JSON string. When JQuery is doing JSON.parse("") it catches that error and fires the global event ajaxError. Except for that it doesn't do anything about it, so if you don't catch that event you will never notice it.

itmammoth commented 4 years ago

I have tried to reproduce it with the code you posted, but nothing wrong would happen. As you say reporder just resturns head :ok and this is very tipical way for api application, me think. How do you POST and handle the result in your javascript? There seems to be a problem with it...

per-d commented 4 years ago

I'm not doing anything with he Ajax request, it's handled by your gem. Can you please try to set a "breakpoint" in JQuery to see what happens when the Ajax request gets an answer and tries to parse it? In my version of jquery2.js it's in the function function ajaxConvert and the line response = conv( response ) (at line 7799). In my app it's where the error happens, the error is catched 2 lines below and then JQuery fires the global event ajaxError.

If you can do that you will also be able to see the exact response value, in my app it's the empty string "". Perhaps that is depending on some parameter in Rails how to respond to Ajax?

itmammoth commented 4 years ago

Please make a small app that can reproduce it, push somewhere to show us.

per-d commented 4 years ago

If you compare building a small app to show you, or make a breakpoint where JQuery is doing JSON.parse it seems to be a big difference.

itmammoth commented 4 years ago

Sorry, I can't be any help of you.

per-d commented 4 years ago

Sorry, I can't be any help of you.

I can't really see the problem with you just testing with a breakpoint at JSON.parse in JQuery. But thanks anyway.