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

Naveed Massjouni naveedm9 at gmail.com
Mon Oct 11 07:18:02 CEST 2010


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;

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

-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
> =======================================================================
>


More information about the Dancer-users mailing list