[Dancer-users] to_json not JSON-ifying the entire variable

P Kishor punk.kish at gmail.com
Mon Oct 11 07:26:44 CEST 2010


On Mon, Oct 11, 2010 at 12:18 AM, Naveed Massjouni <naveedm9 at gmail.com> wrote:
> On Mon, Oct 11, 2010 at 1:04 AM, P Kishor <punk.kish at gmail.com> wrote:
>> On Sun, Oct 10, 2010 at 11:49 PM, Naveed Massjouni <naveedm9 at gmail.com> wrote:
>>> On Sun, Oct 10, 2010 at 11:18 PM, P Kishor <punk.kish at gmail.com> wrote:
>>>> On Thu, Oct 7, 2010 at 5:03 PM, P Kishor <punk.kish at gmail.com> wrote:
>>>>> I have a data object in JavaScript that I am JSONifying, sending to
>>>>> the server (using jQuery ajax) and storing in a SQLite table. In
>>>>> SQLite, the values look like so (I have prettified it by adding
>>>>> returns and tabs)
>>>>>
>>>>> [
>>>>>    {
>>>>>        "a":{"aa":0,"ab":448960000,"ac":"140075520.00"},
>>>>>        "b":1,
>>>>>        "c":"foo"
>>>>>    }
>>>>> ]
>>>>>
>>>>> I retrieve it via ajax again, and use Dancer's to_json method to send
>>>>> the result back. In Firebug, it shows up as
>>>>>
>>>>> [
>>>>>    {
>>>>>        "a":"{\"aa\":0,\"ab\":448960000,\"ac\":\"140075520.00\"}",
>>>>>        "b":1,
>>>>>        "c":"foo"
>>>>>    }
>>>>> ]
>>>>>
>>>>> In other words, to_json seems to stringify all 2nd-level and deeper
>>>>> values. As a result, while the entire value is returned as a JSON
>>>>> object, its internal parts are recognized as strings. That doesn't
>>>>> seem right, no? Its like drinking a cup of coffee, but three sips in
>>>>> finding it to be hot chocolate.
>>>>>
>>>>> I can get around it by reparsing the strings as JSON, but it really
>>>>> shouldn't be so. The data are stored in the SQLite table as a string,
>>>>> so to_json should JSON-ify it all the way through, and send it back as
>>>>> a fully-formed JSON object.
>>>>>
>>>>
>>>>
>>>> The above is really proving to be a bit of a headache for me. Because
>>>> to_json is escaping the quotes in the variable, I am not able to
>>>> reconstruct the JSON object back in my browser. I am using the json
>>>> converter from http://www.json.org/json2.js to convert, but I am
>>>> getting a "syntax error" when I try to use `JSON.parse(data)` where
>>>> data has been retrieved by the browser.
>>>>
>>>> Any suggestions.
>>>>
>>>> --
>>>> Puneet Kishor
>>>> _______________________________________________
>>>> Dancer-users mailing list
>>>> Dancer-users at perldancer.org
>>>> http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
>>>>
>>>
>>> I have written this simple dancer app which works fine:
>>>
>>> #!/usr/bin/env perl
>>> use Dancer;
>>>
>>> get '/' => sub {
>>>    return q[
>>>    <html>
>>>    <head>
>>>    <script>
>>>    function foo() {
>>>        var x = new XMLHttpRequest();
>>>        x.open("GET", "/foo", false);
>>>        x.send();
>>>        alert(x.responseText);
>>>    }
>>>    </script>
>>>    </head>
>>>    <body>
>>>    <input type="button" value="Go" onclick="foo()" />
>>>    </body>
>>>    </html>
>>>    ];
>>> };
>>>
>>> get '/foo' => sub {
>>>    return q[
>>>    {
>>>        "a": {"aa":0,"ab":448960000,"ac":"140075520.00"},
>>>        "b": 1,
>>>        "c": "foo"
>>>    }
>>>    ];
>>> };
>>>
>>> dance;
>>>
>>> The problem I think you are having is that you are calling to_json on
>>> a json string.  You are serializing something that is already
>>> serialized.  Just return what is in your sqlite database without
>>> calling to_json on it.
>>
>>
>> Yes, that is exactly what is happening. So, first, why am I (was I) doing so?
>>
>> Well, see, my json string is a column in a db table. My Dancer app
>> gets a record_id via an ajax query and selects from the table
>>
>> SELECT col1, col2, col3 FROM table WHERE id = ?
>>
>> ('col3' above is holding the json string).
>>
>> Now, I need to send the above results back to the browser. So, I was
>> doing the following
>>
>>              return to_json($sth->fetchall_arrayref({}))
>>
>> The above would send back a json-ified array of hashes to the browser.
>> This works well if all the columns are simple scalars, but is
>> problematic because of the double json-fication.
>>
>> So, now I am doing the following
>>
>>            my @str = ();
>>            while (my ($col1, $col2, $col3) = $sth->fetchrow_array) {
>>                push @str, "{'col1': $col1, 'col2': '$col2', 'col3': $col3}";
>>            }
>>            my $str = '[' . join(',', @str) . ']';
>>            return $str;
>>
>> Then, on the browser side, I do a
>>
>>           var d = eval('(' + data + ')');
>>
>> where 'data' is the text $str returned from the server (I am now
>> making sure to request a 'text' value back -- I am using jQuery's ajax
>> method).
>>
>> So, things are working now, but I really shouldn't be using eval() on
>> the JavaScript side. But I don't know how to get around this.
>>
>> A little bit of background -- on the browser side, my app is keeping
>> track of a number of buttons and choices that the user clicks on and
>> values that the user enters. I store all the choices and values
>> entered in a JavaScript object (a nested array of hashes of arrays,
>> and so on). When the user wants to save the entire session, I
>> basically stringify the JS object and send it to the server where I
>> store it in 'col3' in the db table, which I can retrieve at a later
>> time to reconstruct the entire user session... kinda like poor-man's
>> freeze-thaw.
>
> What you should do is deserialize col3, construct your data structure,
> and then serialize the whole thing.  So for example:
>
>    my @records = ();
>    while (my ($col1, $col2, $col3) = $sth->fetchrow_array) {
>        push @records, {
>            col1 => $col1,
>            col2 => $col2,
>            col3 => from_json($col3)
>        };
>    }
>    return to_json \@records;
>


Oh! what a great idea! So simply, and yet, I didn't even think of it.
Of course, it works splendidly, and no more evals in my JavaScript
now.

Thanks Naveed.

> Also, you should consider using a database plugin such as
> Dancer::Plugin::Database or Dancer::Plugin::DBIC.
>

Maybe. That side of the application ain't broken yet, so, maybe I will
experiment with those modules when things slow down. :-)

Many thanks again for your guidance.


> -Naveed
>
>>
>>>
>>> -Naveed
>>> _______________________________________________
>>> Dancer-users mailing list
>>> Dancer-users at perldancer.org
>>> http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
>>>
>>
>>
>>
>> --
>> Puneet Kishor http://www.punkish.org
>> Carbon Model http://carbonmodel.org
>> Charter Member, Open Source Geospatial Foundation http://www.osgeo.org
>> Science Commons Fellow, http://sciencecommons.org/about/whoweare/kishor
>> Nelson Institute, UW-Madison http://www.nelson.wisc.edu
>> -----------------------------------------------------------------------
>> Assertions are politics; backing up assertions with evidence is science
>> =======================================================================
>>
> _______________________________________________
> Dancer-users mailing list
> Dancer-users at perldancer.org
> http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
>



-- 
Puneet Kishor http://www.punkish.org
Carbon Model http://carbonmodel.org
Charter Member, Open Source Geospatial Foundation http://www.osgeo.org
Science Commons Fellow, http://sciencecommons.org/about/whoweare/kishor
Nelson Institute, UW-Madison http://www.nelson.wisc.edu
-----------------------------------------------------------------------
Assertions are politics; backing up assertions with evidence is science
=======================================================================


More information about the Dancer-users mailing list