Dart decode escaped JSON - json

I'm trying to deserialize a simple JSON object from an API.
The API returns the JSON in escaped quotes since the data represents a user's quote.
test("escaped quoted json test", () {
var s = '''{"quote": "\"a quote from a user\""}''';
var b = json.decode(s);
expect(b["quote"], "\"a quote from a user\"");
});
However this throws:
FormatException: Unexpected character (at character 13)
{"quote": ""a quote from a user""}
Btw the JSON is valid:
{"quote": "\"a quote from a user\""}
How do I tell Dart to handle this correctly?
Thanks in advance.

The inner quote needs to be escaped with a literal backslash not an escaped backslash
var s = '''{"quote": "\\"a quote from a user\\""}''';
or
var s = r'''{"quote": "\"a quote from a user\""}''';
There is a difference between JSON written in Dart source code and JSON received over network.
If you put it in source like in your question, the string is interpreted. You can either adapt the string (double all \) or prefix it with r for raw string.

Related

How to include a JSON encoded object as string in another object which will also be encoded in string

Suppose you have the following JSON object:
{"name":"John Smith",
"jsonData": "{\"comment\":\"He said \\\"It will work\\\", and we are waiting.\"}"
}
The question is how to convert the above object to a string using say JavaScript JSON.stringify() and be able to save it in a text field in the DB and retrieve it later, parse it, and also part the inner encoded object jsonData?
The problem is faced in JavaScript and Java. For simplicity, I will reproduce the problem in JavaScript:
var jsonStr = `{"name":"John Smith",
"jsonData": "{\\\"comment\\\":\\\"He said \\\"It will work\\\", and we are waiting.\\\"}"
}`;
var obj = JSON.parse(jsonStr);
var comments = JSON.parse(obj.jsonData);
console.log(comments)
The above is failing with the error: Uncaught SyntaxError: Unexpected token I in JSON at position 21
And, I couldn't figure out how to include a quoted string in the inner encoded JSON string He said "It will work".
I want the solution in both Java and JavaScript.
Have you considered base64 encoding the JSON string?
Read more about base64 encoding objects here:
Base64 encode a javascript object

Golang json.Unmarshal invalid character '\n' in string literal

Golang json.Unmarshal throws error for newline character. Go Playground
How to unmarshal data if string contains newline?
Simply escaping the newline character should do the trick:
var val []byte = []byte(`"{\"channel\":\"buupr\\niya\",\"name\":\"john\", \"msg\":\"doe\"}"`)
The output for the above:
{"channel":"buupr\niya","name":"john", "msg":"doe"}
Since you're attempting to pass a raw string literal here, you will need to be able to represent the JSON in string form, which requires you to escape the newline character.

Ruby parse string to json

So I have some json that looks like this, which I got after taking it out of some other json by doing response.body.to_json:
{\n \"access_token\": \"<some_access_token>\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 3600,\n \"id_token\": \<some_token>\"\n}\n"
I want to pull out the access_token, so I do
to_return = {token: responseJson[:access_token]}
but this gives me a
TypeError: no implicit conversion of Symbol into Integer
Why? How do I get my access token out? Why are there random backslashes everywhere?
to_json doesn't parse JSON - it does the complete opposite: it turns a ruby object into a string containing the JSON representation of that object is.
It's not clear from your question what response.body is. It could be a string, or depending on your http library it might have already been parsed for you.
If the latter then
response.body["access_token"]
Will be your token, if the former then try
JSON.parse(response.body)["access_token"]
Use with double quotes when calling access_token. Like below:
to_return = {token: responseJson["access_token"]}
Or backslashes are escaped delimiters and make sure you first parse JSON.

Importing JSON into R with in-line quotation marks

I'm attempting to read the following JSON file ("my_file.json") into R, which contains the following:
[{"id":"484","comment":"They call me "Bruce""}]
using the jsonlite package (0.9.12), the following fails:
library(jsonlite)
fromJSON(readLines('~/my_file.json'))
receiving an error:
"Error in parseJSON(txt) : lexical error: invalid char in json text.
84","comment":"They call me "Bruce""}]
(right here) ------^"
Here is the output from R escaping of the file:
readLines('~/my_file.json')
"[{\"id\":\"484\",\"comment\":\"They call me \"Bruce\"\"}]"
Removing the quotes around "Bruce" solves the problem, as in:
my_file.json
[{"id":"484","comment":"They call me Bruce"}]
But what is the issue with the escapement?
In R strings literals can be defined using single or double quotes.
e.g.
s1 <- 'hello'
s2 <- "world"
Of course, if you want to include double quotes inside a string literal defined using double quotes you need to escape (using backslash) the inner quotes, otherwise the R code parser won't be able to detect the end of the string correctly (the same holds for single quote).
e.g.
s1 <- "Hello, my name is \"John\""
If you print (using cat¹) this string on the console, or you write this string on a file you will get the actual "face" of the string, not the R literal representation, that is :
> cat("Hello, my name is \"John\"")
Hello, my name is "John"
The json parser, reads the actual "face" of the string, so, in your case json reads :
[{"id":"484","comment":"They call me "Bruce""}]
not (the R literal representation) :
"[{\"id\":\"484\",\"comment\":\"They call me \"Bruce\"\"}]"
That being said, also the json parser needs double-quotes escaping when you have quotes inside strings.
Hence, your string should be modified in this way :
[{"id":"484","comment":"They call me \"Bruce\""}]
If you simply modify your file by adding the backslashes you will be perfectly able to read the json.
Note that the corresponding R literal representation of that string would be :
"[{\"id\":\"484\",\"comment\":\"They call me \\\"Bruce\\\"\"}]"
in fact, this works :
> fromJSON("[{\"id\":\"484\",\"comment\":\"They call me \\\"Bruce\\\"\"}]")
id comment
1 484 They call me "Bruce"
¹
the default R print function (invoked also when you simply press ENTER on a value) returns the corresponding R string literal. If you want to print the actual string, you need to use print(quote=F,stringToPrint), or cat function.
EDIT (on #EngrStudent comment on the possibility to automatize quotes escaping) :
Json parser cannot do quotes escaping automatically.
I mean, try to put yourself in the computer's shoes and image you should parse this (unescaped) string as json: { "foo1" : " : "foo2" : "foo3" }
I see at least three possible escaping giving a valid json:
{ "foo1" : " : \"foo2\" : \"foo3" }
{ "foo1\" : " : "foo2\" : \"foo3" }
{ "foo1\" : \" : \"foo2" : "foo3" }
As you can see from this small example, escaping is really necessary to avoid ambiguities.
Maybe, if the string you want to escape has a really particular structure where you can recognize (without uncertainty) the double-quotes needing to be escaped, you can create your own automatic escaping procedure, but you need to start from scratch, because there's nothing built-in.

JSON.parse file input differ from parsing string literal

Im using nodejs to parse some JSON files and insert them into mongodb,the JSON in these files have invalid JSON characters like \n,\" etc ..
The thing that i dont understand is that if i tried to parse like :
console.log(JSON.parse('{"foo":"bar\n"}'))
i get
undefined:1
{"foo":"bar
but if i tried to parse the input from the file (The file has the same string {"foo":"bar\n"})like:
new lazy(fs.createReadStream("info.json"))
.lines
.forEach(function(line){
var line = line.toString();
console.log(JSON.parse(line));
}
);
every thing works fine , i want to know if this fine and its ok to parse the files i have, or i should replace all invalid JSON characters before i parse the files ,
and why is there a difference between the two.
Thanks
If you can read "\n" if your text file, then it's not an end of line but the \ character followed by a n.
\n in a JavaScript string literal adds an end of line and they're forbidden in JSON strings.
See json.org :
To put an end of line in a JSON string, you must escape it, which means you must escape the \ in a JavaScript string so that there's "\n" in the string received by JSON.parse :
console.log(JSON.parse('{"foo":"bar\\n"}'))
This would produce an object whose foo property value would contain an end of line :