Accessing list of dictionaries in jQuery

1,042 views
Skip to first unread message

Larry Martell

unread,
Apr 8, 2013, 7:53:09 PM4/8/13
to django...@googlegroups.com
I am passing a list of dictionaries to my template. In the template
language I can do this and it works as expected:

{% for row in images %}
<div class="gImage-row gImage_row-{{ forloop.counter0 }}">
<a class='no-highlight' href="{{ IMAGE_DIR }}{{ row.image }}"
rel="superbox[image]">
<img class='gImage' src="{{ IMAGE_DIR }}{{ row.image }}"
onerror="noimage(event)">
</a>
</div>
{% endfor %}

But I need to process this data in jQuery. If I pass images into a
function like this:

my_func({{ images }});

I get a syntax error, 'unexpected token &'

And if I pass it in like this:

my_func("{{ images }}");

It is received in the function as a character string, not as a list of
dictionaries. How can I pass this to my function and have it be
received as the list of dictionaries that it is?

Nikolas Stevenson-Molnar

unread,
Apr 8, 2013, 8:01:00 PM4/8/13
to django...@googlegroups.com
Injecting data into a template can be tricky. I would recommend doing
two things:

1) Serialize your data to JSON in your view first using Python's json
module. Something like this:
>>> images_as_json = json.dumps(images)

2) Rather than trying to inject it directly into JavaScript, which can
cause encoding-related issues, dump your JSON-formatted string into a
hidden node on page, then read it out and parse it into a JS object. So,
for example:

<div style="display: none;" id="myData">{{ images_as_json }}</div>
<script type="text/javascript>
var images = $.parseJSON($('#myData').html();
</script>

_Nik

Larry Martell

unread,
Apr 8, 2013, 8:24:28 PM4/8/13
to django...@googlegroups.com
I appreciate the suggestion, but using a hidden field sounds very
kludgy. Is there no other way?
> --
> You received this message because you are subscribed to the Google Groups "Django users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
> To post to this group, send email to django...@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-users?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

Nikolas Stevenson-Molnar

unread,
Apr 8, 2013, 8:36:24 PM4/8/13
to django...@googlegroups.com
Injecting data into client code is bound the be kludgy any way you slice it. The reason for passing it through a hidden element has to do with correct escaping of characters. Consider the following:

$.parseJSON("{{ images_as_json }}");

and lets say this is rendered as:

$.parseJSON("{foo: "bar"}");

See the problem? Yes, you could use single quotes, as in $.parseJSON('{foo: "bar"}') but if any of your serialized data contain single quotes (or an apostrophe), then you're back to the same problem. You could URL-encode your serialized JSON string and then pass it through decodeURIComponent() in JS, but I've found that to not always be reliable. Injecting the JSON string into an element removes all of those problems. And IMHO it's less kludgy, as your data isn't being injected directly into your client-side code; rather, your code is "loading" the data from a node in the DOM.

Others may have come up with other ways around this (I suspect many just load the data asynchronously), but this is the most reliable method I've come up with to get data into a client-side script without an asynchronous call.

_Nik

Tom Evans

unread,
Apr 9, 2013, 4:45:47 AM4/9/13
to django...@googlegroups.com
On Tue, Apr 9, 2013 at 1:24 AM, Larry Martell <larry....@gmail.com> wrote:
> I appreciate the suggestion, but using a hidden field sounds very
> kludgy. Is there no other way?
>

Remember that JSON = JavaScript Object Notation - its a way of writing
literal JS objects.

<script type="javascript">
var data = {{ json_encoded_literal }};
</script>

You've got to fully trust the data that you have encoded! If I was
dealing with user generated content, it would go in an element, or
loaded over AJAX.

Cheers

Tom

Larry Martell

unread,
Apr 9, 2013, 8:11:17 AM4/9/13
to django...@googlegroups.com
I have no issue with using JSON - it's the hidden field I don't like.
But it's what I'm going to implement later today.

Larry Martell

unread,
Apr 9, 2013, 1:04:11 PM4/9/13
to django...@googlegroups.com
Thanks! This works perfectly.

On Mon, Apr 8, 2013 at 6:01 PM, Nikolas Stevenson-Molnar
<nik.m...@consbio.org> wrote:
Reply all
Reply to author
Forward
0 new messages