4

Problem

I'm getting a parse error on some of my json data, because it includes single quotes. For example, some of my data could look like this:

"Larry's data"

I've read the following article: jQuery single quote in JSON response

and I've been trying to implement some of the solutions but I haven't been able to get rid of my parse error.

Code

In my model, I'm using a lua library to encode my data as json. The model returns data that looks like this:

[{\"createddatetime\":\"2013-09-10 17:56:55\",\"description\":\"John Doe\'s phone\",\"number\":\"72051\",\"createdname\":\"conversion script\",\"user\":\"23123\",\"position\":\"46\",\"id\":\"49\",\"user_id\":\"822\",\"password\":\"rwer234\"}]"

In my view, my code currently looks like this:

  $.ajax({
      url:myurl + '?startpos=' + page_index * items_per_page + '&numberofrecordstograb=' + items_per_page + '&viewtype=json',

      success: function(data){            

            console.log('inside');    
             for(var i=0;i<data.length;i++) {
                        var deviceobj = data[i];                        
                        newcontent = newcontent + "<TR>";
                        newcontent=newcontent + '<TD>';    

                        //add EDIT hyperlink
                        if ($("#editdevicesettings").val() == "true") {              
                            var temp  = $("#editlinkpath").val();
                            newcontent=newcontent +  temp.replace("xxx",deviceobj["device_id"]) + '&nbsp;&nbsp;';
                        } 

                        //add DELETE hyperlink
                        if ($("#deletedevice").val() == "true") {              
                            var temp  = $("#deletelinkpath").val();
                            newcontent=newcontent +  temp.replace("xxx",deviceobj["device_id"]);
                        }                                 
                        newcontent=newcontent + '</TD>';

                        newcontent=newcontent + '<TD>' + deviceobj["number"] +'</TD>';
                        newcontent=newcontent + '<<TD>' + deviceobj["user"] + '</TD>';
                        newcontent=newcontent + '<<TD>' + deviceobj["password"] + '</TD>';
                        if (deviceobj["name"]) {
                              newcontent=newcontent + '<TD>' + deviceobj["name"] + '</TD>';
                        } 
                        else  {
                             newcontent=newcontent + '<TD>&nbsp;</TD>';
                        }
                        newcontent=newcontent + '<TD>' + unescape(deviceobj["description"])  + '</TD>';
                        newcontent = newcontent + "</TR>";         
                }// end for 
                // Replace old content with new content
                $('#Searchresult').html(newcontent);                    
            }//end if

      },
      error: function(request, textStatus, errorThrown) {
        console.log(textStatus);
        console.log('========');
        console.log(request);

      },
      complete: function(request, textStatus) { //for additional info
        //alert(request.responseText);
        console.log(textStatus);
      }
    });

But I still get the parse error on this particular record.

Any suggestions would be appreciated. Thanks.

EDIT 1

I've changed my logic so that when it fails, it print out "request.responseText" into the console. Here's what it looks like:

"[{\"createddatetime\":\"2013-09-10 17:56:55\",\"description\":\"John Doe\'s phone\",\"number\":\"72051\",\"createdname\":\"conversion script\",\"user\":\"28567\",\"position\":\"46\",\"id\":\"49\",\"user_id\":\"822\",\"password\":\"rwer234\"}]"

The apostrophe is still escaped.

EDIT 2

Here's what my code looks like on the server side (aka. in the model):

get_device_records = function(ajaxdata)
   local results = list_devices(nil,false,ajaxdata.startpos, ajaxdata.numberofrecordstograb)
   return results.value
end
Community
  • 1
  • 1
dot
  • 14,928
  • 41
  • 110
  • 218
  • 1
    I think your json data in not valid, http://jsonlint.com/ – defau1t Oct 10 '13 at 18:41
  • yeah. i've tried testing in jsonlint but all my json data fails. i don't know why. but the browser is able to parse everything... except the ones with single quotes in them. i'd like to know why my data fails in jsonlint. – dot Oct 10 '13 at 18:42
  • You have `dataType: 'json'` so, don't need to parse it manually, `jQuery` will do it, it's (data) already parsed object, also `"` are escaped, it's should be uncapped. – The Alpha Oct 10 '13 at 18:44
  • 1
    Your example showing what the model returns is not valid at all - in real JSON, the regular double-quotes should not be escaped like that, so I'm guessing you pulled that from a debugger somewhere. Use Fiddler or your browser dev tool to watch the actual AJAX response to get the raw response. – Joe Enos Oct 10 '13 at 18:47
  • Joe Enos, I'm using Chrome's debug tools and under the Network tab, I can see all the responses I get for each ajax call. ALL my json data looks the same, and is being parsed correctly... ? I'm too new to json to know why/how it's working... but it is. The only ones that fail are the ones with the single quotes. – dot Oct 10 '13 at 18:57
  • Recovering Since 2003, if i remove the parseJSON() call, all data comes back as undefined. i'm going to update my original post to show you how I'm looping through the json object... – dot Oct 10 '13 at 19:05
  • Look, this error is being triggered before the success event. So you have to treat this on the server side. As i said bellow, it's about the double slashes around the single quotes. – Jacobson Oct 10 '13 at 19:09
  • The apostrophe is absolutely valid in JSON. Your problem is the JSON-encoded JSON string. – Bergi Oct 10 '13 at 19:17
  • Bergi would you mind expanding a little? I'm pretty green. And I'm trying to filter through everyone's comments. An answer with clear instructions would be helpful. Thank you! – dot Oct 10 '13 at 19:18

4 Answers4

6

Looks like you are doing double serialisation on the server side. Happens for example if your web framework automatically serialises the returned object but you make an extra explicit, unnecessary serialise call on your object. The fact that your code works with no ' cases proves this: jquery makes one parse automatically (because of the dataType) then you run another parseJSON. That shouldn't work :) Fix your serialisation on the server side and remove the unnecessary parseJSON call from your success method. Every other solution is just a workaround not a real fix.

peterfoldi
  • 7,451
  • 5
  • 21
  • 19
  • 1
    peterfoldi, please check out edit 2. I don't think I'm doing double serialization on the server side... ?? In my controller, I'm doing a straight pass through of the data from the model to the view. No manipulation done there at all. – dot Oct 10 '13 at 19:08
  • That code doesn't help much without knowing your framework. What my suspicion is that the framework does a serialisation automatically. If I am right then you could remove your encode call on the server side and the parseJSON call from the success method and it should work. – peterfoldi Oct 10 '13 at 19:15
  • hey again. Ok. so I tried to remove the parseJSON call in the view. Also removed all logic to try to do jscript replace stuff. In the model, I've removed the call the json.encode. It still fails on the same record with the apostrophe... but some how it's been escaped. So in Chrome's debug window it looks like "John Doe\'s phone"... Do you want me to post a clean version of current code? – dot Oct 10 '13 at 19:23
  • Sorry for the very stupid question: doesn't your modified code still returns the "jsondata" instead of "results" that is null because you don't assign value to it now? And sorry again for this :) – peterfoldi Oct 10 '13 at 19:28
  • i think you just responded to my "old" comment. I just changed it. I had a bug, yes... where I wasn't returning results.value. But I updated my comment to give you the latest status. Something is still escaping my record with the apostrophe... Trying to figure out what it is. BTW. Thank you very much for your clear explanations / help so far. – dot Oct 10 '13 at 19:34
  • You are getting there I think. So now without the encode on the server side and dataType in the js code your double-quotes are not escaped and also your code works when there is no ' in the names? Then it's time to focus on your server-side code: what's in the "ajaxdata" and what does "value" do with the results. Debug that code. My next guess is that the framework's json serialisation should be ok, so the data is "corrupted" by the time it gets to the return statement. – peterfoldi Oct 10 '13 at 19:46
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/39015/discussion-between-dot-and-peterfoldi) – dot Oct 10 '13 at 19:54
  • the issue is with the framework I'm using. it is automatically calling json.encode on the data in the view. – dot Oct 10 '13 at 20:41
  • Peterfoldi... You legend... thank you for that explanation... hit a "light bulb moment" and helped me in a similar situation... – EaziLuizi Oct 27 '15 at 08:18
4

try replacing

data = data.replace("\\'", "'");

with

data = data.replace(/[\\"']/g, '\\$&').replace(/\u0000/g, '\\0');

I had a similar problem with parsing JSON data and this code from another answer solved it

Community
  • 1
  • 1
David Hariri
  • 969
  • 4
  • 15
1

This is a bug in the lua json.encode function of the json4lua 0.9.40 library. It erroneously escapes single quotes. This is corrected in 0.9.50:

https://github.com/craigmj/json4lua

Jaffadog
  • 664
  • 8
  • 16
0

Just take out the \\ from the json response. I mean, pass the single quote as it is, like this:

[{\"createddatetime\":\"2013-09-10 17:56:55\",\"description\":\"John Doe's phone\",\"number\":\"72051\",\"createdname\":\"conversion script\",\"user\":\"23123\",\"position\":\"46\",\"id\":\"49\",\"user_id\":\"822\",\"password\":\"rwer234\"}]"
Jacobson
  • 674
  • 5
  • 10
  • I'm using a lua library and in my model, i do this something like this " local jsondata = json.encode(results.value)" and that encodes the entire string....I guess I can try to play around with it to find the \\'s and replace it with "'" – dot Oct 10 '13 at 18:59
  • there's no need to use data.replace("\\'", "'") too. – Jacobson Oct 10 '13 at 19:00
  • Jacobson, I added logic in the model to remove the "\\" right after I encode it as jsondata. But it still fails because the string now looks like "John Doe\'s phone". Please check out EDIT 1 of my post. – dot Oct 10 '13 at 19:14