1

I'm running into an issue with parsing JSON data into a dict which I cannot figure out.

I'm connecting to a Tornado websocket from JavaScript and sending the following data, entered into a textfield:

{"action": "something"}

The way I'm sending it to the websocket is:

sock.send( JSON.stringify( $('textfield').value ) );

Now in Python I have the following code in my WebsocketHandler::on_message():

print("Message type: " + str(type(message)) + ", content: " + message)

parsed_message = json.loads(message)

print("Parsed message type: " + str(type(parsed_message)) + ", content: " + parsed_message)

And the output from this is:

Message type: <type 'unicode'>, content: "{\"action\":\"START_QUESTION_SELF\"}"
Parsed message type: <type 'unicode'>, content: {"action":"START_QUESTION_SELF"}

Now I would expect the second printed message to be a dict and I cannot figure out why this isn't working. Any help would be greatly appreciated.

5
  • Sorry if i've misunderstood but content: {"action":"START_QUESTION_SELF"} is actually a dict. Commented May 12, 2016 at 8:19
  • Are you using python2 or 3? Commented May 12, 2016 at 8:20
  • @M.T, I'm using Python 2.7 Commented May 12, 2016 at 8:20
  • @SerhanOztekin It's being received as a unicode string, and after a call to json.loads() it's still seen as a unicode object and I cannot use it as a dict. Commented May 12, 2016 at 8:22
  • I am unable to reproduce this using python 2.7. I get Parsed message type: <type 'dict'> Commented May 12, 2016 at 8:24

2 Answers 2

3

It doesn't work because when you do sock.send(JSON.stringify('{"action": "something"}')); you send this "{\"action\": \"something\"}"

When you print message you can verify that it actually contains quotes. Hence, it is being interpreted as a string by json.loads.

Easiest solution would be invoking json.loads again:

parsed_message = json.loads(json.loads(message))

However you should really consider converting textfield value into an object and then using JSON.stringify on it. Something like this:

sock.send(JSON.stringify(JSON.parse( $('textfield').value)));
Sign up to request clarification or add additional context in comments.

2 Comments

I changed the sending of of the data to: sock.send(JSON.stringify(JSON.parse($('textfield').value))); And now get a dict on the Python end. Thanks!
@Revell Huh. I've just proposed the very same solution :)
0

I seems like your string is escaped (\"), and thus json.loads sees it as a plain string.
Try to unescape message before calling json.loads.

I've had the same error when using JSONField in models and setting the json to this

content='{"content":"Hello A","numbers":[1,2,3,4]}'
# json.loads(model.content) --> type 'str'

Instead of

content={"content":"Hello A","numbers":[1,2,3,4]}
# json.loads(model.content) --> type 'dict'

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.