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

P Kishor punk.kish at gmail.com
Mon Oct 11 07:04:21 CEST 2010


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.




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