0

I have a nodeJS server configured with Express and BodyParser

const express = require('express')
const expressWs = require('express-ws')
const bodyParser = require('body-parser')
app.ws('/ws', websocket)

When the websocket gets a message I pass it on

ws.onmessage = e => {
    const {action, payload} = JSON.parse(e.data)
    channel.send(action,payload)
}

However when it comes to the app via the channel it's got lots of extra characters in it

"{\"action\":\"guide_data_retreived\",\"payload\":[{\"id\":544,\"json\":\"{\\\"code\\\":\\\"lPvwP4rz\\\",\\\"coverDesign\\\":null,\\\"created\\\":1535018423000,\\\"description\\\":\\\"{\\\\\\\"blocks\\\\\\\":[{\\\\\\\"key\\\\\\\":\\\\\\\"dpcth\\\\\\\",\\\\\\\"text\\\\\\\":\\\\\\\"This is an example of a medical emergency. \\\\\\\",\\\\\\\"type\\\\\\\":\\\\\\\"unstyled\\\\\\\",\\\\\\\"depth\\\\\\\":0,\\\\\\\"inlineStyleRanges\\\\\\\":[],\\\\\\\"entityRanges\\\\\\\":[],\\\\\\\"data\\\\\\\":{}},

Which makes it unparseable.

Any idea where this is coming from and how to fix it?

2
  • why don't you use JSON.stringify to send it out? Commented Feb 26, 2019 at 10:01
  • The problem here is too much stringify and not enough parse Commented Feb 26, 2019 at 10:46

1 Answer 1

1

The problem is that you have several levels of string-encoded JSON nested within your objects.

The \'s are escape characters. They are there to indicate that the quote following them is not a terminating quote, but rather is a character in the string. So for instance, let's say I want to have a javascript object which looks like this:

// myFile.javascript
{ "x" : "abc" }
const s = JSON.stringify(foo) // s is a string

Then s will include these escape characters, so that the quotes around "x" and "abc" will be interpreted as inside the string rather than as string terminators:

s == "{\"x\":\"abc\"}" // -> true

So since s is a string, you can also put it inside another object, like this:

const bar = { "nested" : s }

And if you stringify that, you will end up with another level of escapes to signify that s is a string and not a nested JSON object within the object:

JSON.stringify(bar) == "{\"nested\":\"{\\"x\\":\\"abc\\"}\"}

So it's clear that within your application, you're passing around strings instead of objects. For instance, inside your payload, json is a nested string-encoaded JSON, and inside json, description is string-encoaded-JSON.

If you have control over the message being sent on this websocket, then you should parse those strings before you put them in the payload.

So for instance, if you are building the payload like this:

func sendMessage(ws, action, id, json) {
  ws.send(action, {id: id, json: json})
}

then you should change it to this:

func sendMessage(ws, action, id, json) {
  ws.send(action, {id: id, json: JSON.parse(json)})
}

And so on, for each level of nested object.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.