1

When I post data to the server as JSON via AJAX, values from form elements come is as strings (unicode). Here's a simple example:

<select id="test">
  <option value=1>One</option>
  <option value=2>Two</option>
  <option value=3>Three</option>
</select>

Sending data to the server like this:

$('test').change(function(){
  var id = $(this).val();
  $.ajax(
  {
    type: 'POST',
    contentType: 'application/json; charset=utf-8',
    url: someUrl,
    data: JSON.stringify(id:id),
    dataType: 'json',
    success: doSomething
  });

Then on the server (Pyramid 1.3.3):

log.debug(type(request.json_body['id'])) gives <type 'unicode'>

This makes code like if request.json_body['id'] == 2 False since the value is actually u'2'.

I've been doing id = int(request.json_body['id']) for all the params that should be ints, but is there a better way? I feel like I'm missing something obvious.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Hollister
  • 3,758
  • 2
  • 20
  • 22

1 Answers1

0

No, this is correct. Form element values in a web page are always strings, regardless of what you expect the end-users to enter.

You can use collander to automate the conversion on the server side though. You specify a schema, pass in the decoded JSON data structure and get a nice Python structure back, fully validated.

The simplest possible example for deserializing integers:

>>> import colander
>>> id = colander.SchemaNode(colander.Integer())
>>> id.deserialize('1')
1

but colander can handle mappings, sequences, booleans, datetime objects, and much more besides.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Interesting, I'll check that out. But it's not just form element values...a literal integer like `{id:2}` also gets received as string on the server. – Hollister Sep 01 '12 at 20:53
  • Are you absolutely certain of that? See http://pyramid.readthedocs.org/en/latest/narr/webob.html#request-json-body; the examples clearly contradict you. – Martijn Pieters Sep 01 '12 at 21:00
  • Ah, no...my mistake. I meant to say that I tested a literal option element ` – Hollister Sep 01 '12 at 21:06
  • Colander looks great for complex decoding/validation, but for this simple issue, defining schemas for all possible objects is more effort than just an `int()` call. Thanks for the info, though. – Hollister Sep 01 '12 at 21:10
  • That's still a HTML form element, and it's value will be a string, regardless of whether you used quotes there to surround the value. Quotes around attributes are required but most browsers tolerate their absence; they do not denote a string vs. an integer like in python.. – Martijn Pieters Sep 01 '12 at 21:11
  • Yes, colander is meant for more complex examples of course; just use `int()` for the simple cases. – Martijn Pieters Sep 01 '12 at 21:11