[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