This isn't so much a problem as a solution I found, and have no idea how it's working. I was making a fetch call and receiving a text response that I needed to convert to workable JSON.
"[{\"Rank\":1,\"FISHERMAN_PHONENAME\":\"James Elam\"...}]"
One JSON.parse knocked off the end double quotes and the slashes, but it still wasn't coming back as the json array of objects I needed so I ended up doing this:
if (response.ok) {
const payload = await response.text();
data = JSON.parse(JSON.parse(payload));
}
That did the trick, but I have no idea why it needed a double parse to make it happen. Any insight would be awesome.
I have no idea why it needed a double parse to make it happen.
Because the data was double encoded as JSON. JSON would simply be
{"Rank":1,"FISHERMAN_PHONENAME":"James Elam"...}
While
"[{\"Rank\":1,\"FISHERMAN_PHONENAME\":\"James Elam\"...}]"
is also valid JSON, in this case it's a (JSON) string that contains other JSON data.
Here is a simply example that demonstrates double encoding:
console.log('Once', JSON.stringify({foo: 42}));
console.log('Twice', JSON.stringify(JSON.stringify({foo: 42})));
Note how the first one does not include leading and trailing quotes.
You should fix the process that generates the JSON to only encode it once.
Related
I'm reading data using Javascript fetch from an Azure Table Storage, where one of the columns contain a JSON string. So I'm getting back a string that I don't know how to format so that I can parse it.
let jsonData =
'{"Timestamp":"2019-10-01T14:19:48.2593745+00:00","Data":"{\"app_id\":\"apple\",\"dev_id\":\"node1\",\"hardware_serial\":\"001122334455667788\",\"port\":1,\"counter\":63,\"payload_raw\":\"afIWk0ccABwM1Ag=\",\"payload_fields\":{\"doorState\":\"open\",\"humidity\":31,\"location\":{\"lat\":0,\"lon\":0},\"temperature\":22.6},\"metadata\":{\"time\":\"2019-10-01T14:19:48.009374928Z\",\"frequency\":867.9,\"modulation\":\"LORA\",\"data_rate\":\"SF7BW125\",\"coding_rate\":\"4/5\",\"gateways\":[{\"gtw_id\":\"banana\",\"gtw_trusted\":true,\"timestamp\":3579682692,\"time\":\"2019-10-01T14:19:47Z\",\"channel\":7,\"rssi\":-118,\"snr\":-5,\"rf_chain\":0,\"latitude\":0,\"longitude\":0,\"altitude\":172,\"location_source\":\"registry\"},{\"gtw_id\":\"banana\",\"timestamp\":567219172,\"time\":\"2019-10-01T14:19:47.98531Z\",\"channel\":7,\"rssi\":-55,\"snr\":10,\"rf_chain\":0,\"latitude\":0,\"longitude\":0,\"location_source\":\"registry\"}]},\"downlink_url\":\"https://www.someurl.com\"}"}';
After some testing I see that the escape backslashes cause problems, in addition to the quotation marks around the inner JSON object.
In short, parsing this fails:
let jsonData2 = '{"Test":"21342345","Data":"{\"test\":\"ethneipnrt\"}"}';
But this works:
let jsonData2 = '{"Test":"21342345","Data":{"test":"ethneipnrt"}}';
But how can I format the string automatically so that parsing works?
I got the parsing to work yesterday by filtering away the unwanted elements. First replacing all instances of '"{' with '{', then replacing all instances of '}"' with '}', and finally removing all backslashes.
let data = jsonData.replace(/"{/g, '{').replace(/}"/g, '}').replace(/\\/g, '');
let parsed = JSON.parse(data);
I agree that this should probably be handled in the backend. But for now it's enough to get the page up and running.
I am Trying to retrieve data from json in my code. Json data doesn't contain any brackets. It is just any array separated by commas(,). My Problem is that when I get data using $scope, an extra sqaure bracket get added outside my output. Demo of my code is
controller.js
$http.get("serverUrl")
.success(function(data) {
$scope.sour = data;
})
.error(function(err) {
console.log("Error in source: "+JSON.stringify(err));
});
html
<div>
{{sour}}
</div
expected json
data
error
[data]
I have tried old stack solutions but none of them worked out for me.
Please share if anyone know why this error being produced, As I have used this method a hundred times before but never faced this problem.Regards.
After trying found out a solution.
.toString().replace();
solved out my problem.
As per how JSON.stringify should work as specified here, the result that you explained is as expected.
Let separator be the result of concatenating the comma character,
the line feed character, and indent.
Let properties be a String
formed by concatenating all the element Strings of partial with each
adjacent pair of Strings separated with separator. The separator
String is not inserted either before the first String or after the
last String.
Let final be the result of concatenating "[", the line
feed character, indent, properties, the line feed character,
stepback, and "]"
Which will result in a valid JSON String. The format you are requesting is confusing and is probably an invalid JSON. You can try checking the JSON using some JSON validator online. (Notice that [1,2,3,4] is valid where as 1,2,3,4 is invalid)
You are probably having a service that is expecting a malformed JSON, it will be better to fix that part instead of duck taping your JSON.
Meanwhile, the only thing you are explaining is the format you are getting and the format that is working. You haven't still specified where exactly the error happens? Is it error from HTTP request? Is it error thrown in Javascript? What is causing the error? What error messages are you getting?
I am trying to make sure input from user is converted into a valid JSON string before submitted to server.
What I mean by 'Converting' is escaping characters such as '\n' and '"'.
Btw, I am taking user input from HTML textarea.
Converting user input to a valid JSON string is very important for me as it will be posted to the server and sent back to client in JSON format. (Invalid JSON string will make whole response invalid)
If User entered
Hello New World,
My Name is "Wonderful".
in HTML <textarea>,
var content = $("textarea").val();
content will contain new-line character and double quotes character.
It's not a problem for server and database to handle and store data.
My problem occurs when the server sends back the data posted by clients to them in JSON format as they were posted.
Let me clarify it further by giving some example of my server's response.
It's a JSON response and looks like this
{ "code": 0, "id": 1, "content": "USER_POSTED_CONTENT" }
If USER_POSTED_CONTENT contains new-line character '\n', double quotes or any characters that are must be escaped but not escaped, then it is no longer a valid JSON string and client's JavaScript engine cannot parse data.
So I am trying to make sure client is submitting valid JSON string.
This is what I came up with after doing some researches.
String.prototype.escapeForJson = function() {
return this
.replace(/\b/g, "")
.replace(/\f/g, "")
.replace(/\\/g, "\\")
.replace(/\"/g, "\\\"")
.replace(/\t/g, "\\t")
.replace(/\r/g, "\\r")
.replace(/\n/g, "\\n")
.replace(/\u2028/g, "\\u2028")
.replace(/\u2029/g, "\\u2029");
};
I use this function to escape all the characters that need to be escaped in order to create a valid JSON string.
var content = txt.val().escapeForJson();
$.ajax(
...
data:{ "content": content }
...
);
But then... it seems like str = JSON.stringify(str); does the same job!
However, after reading what JSON.stringify is really for, I am just confused. It says JSON.stringify is to convert JSON Object into string.
I am not really converting JSON Object to string.
So my question is...
Is it totally ok to use JSON.stringify to convert user input to valid JSON string object??
UPDATES:
JSON.stringify(content) worked good but it added double quotes in the beginning and in the end. And I had to manually remove it for my needs.
Yep, it is totally ok.
You do not need to re-invent what does exist already, and your code will be more useable for another developer.
EDIT:
You might want to use object instead a simple string because you would like to send some other information.
For example, you might want to send the content of another input which will be developed later.
You should not use stringify is the target browser is IE7 or lesser without adding json2.js.
I don't think JSON.stringify does what you need. Check the out the behavior when handling some of your cases:
JSON.stringify('\n\rhello\n')
*desired : "\\n\\rhello\\n"
*actual : "\n\rhello\n"
JSON.stringify('\b\rhello\n')
*desired : "\\rhello\\n"
*actual : "\b\rhello\n"
JSON.stringify('\b\f\b\f\b\f')
*desired : ""
*actual : ""\b\f\b\f\b\f""
The stringify function returns a valid JSON string. A valid JSON string does not require these characters to be escaped.
The question is... Do you just need valid JSON strings? Or do you need valid JSON strings AND escaped characters? If the former: use stringify, if the latter: use stringify, and then use your function on top of it.
Highly relevant: How to escape a JSON string containing newline characters using javascript?
Complexity. I don't know what say.
Take the urlencode function from your function list and kick it around a bit.
<?php
$textdata = $_POST['textdata'];
///// Try without this one line and json encoding tanks
$textdata = urlencode($textdata);
/******* textarea data slides into JSON string because JSON is designed to hold urlencoded strings ******/
$json_string = json_encode($textdata);
//////////// decode just for kicks and used decoded for the form
$mydata = json_decode($json_string, "true");
/// url decode
$mydata = urldecode($mydata['textdata']);
?>
<html>
<form action="" method="post">
<textarea name="textdata"><?php echo $mydata; ?></textarea>
<input type="submit">
</html>
Same thing can be done in Javascript to store textarea data in local storage. Again textarea will fail unless all the unix formatting is deal with. The answer is take urldecode/urlencode and kick it around.
I believe that urlencode on the server side will be a C wrapped function that iterates the char array once verses running a snippet of interpreted code.
The text area returned will be exactly what was entered with zero chance of upsetting a wyswyg editor or basic HTML5 textarea which could use a combination of HTML/CSS, DOS, Apple and Unix depending on what text is cut/pasted.
The down votes are hilarious and show an obvious lack of knowledge. You only need to ask yourself, if this data were file contents or some other array of lines, how would you pass this data in a URL? JSON.stringify is okay but url encoding works best in a client/server ajax.
I have json on my page coming from the string property of the model:
var myJson = '[{\"A\":1,\"B\":10,\"C\":\"214.53599548339844\",\"D\":\"72.52798461914062\"},
{\"A\":1,\"B\":11,\"C\":\"214.53599548339844\",\"D\":\"72.52798461914062\"}]'
I want to process that json via javascript on the page
I am doing $.parseJSON(#Html.Raw(Json.Encode(myJason))); but json still contain \" symbol. If i do $.parseJSON(#Html.Raw(Json.Decode(myJason))); it is just producing an $.parseJSON(System.Web.Helpers.DynamicJsonArray); How can I fix that?
Take your JSON and .stringify() it. Then use the .replace() method and replace all occurrences of ("\").
var myString = JSON.stringify(myJson);
var myNewString = myString.replace(/\\/g, "");
Hope this helps.
There are two ways
1 from where you get the JSON asked them to send you as url encoded format. at your end you need to decode url and you will get the Perfect JSON.
Other wise do the laborious replace method for each and every special charecter with respective char.
like above example you need to use replace("\","");
There is no JSON parser that will be able to deal with a JSON string that isn't properly formatted in the first place.
so you need to make sure that your theModel is formatted appropriately and according JSON.org standards.
Like
Koushik say you can use String operation
I have to stringify some JS objects to save the text somewhere and I'd like to be able to copy the saved text manually afterwards and pass it via the console to a function which then parses the text to do something with the original object.
Unfortunately parsing pasted text seems to have problems with escaped double quotes since parsing always fails.
I have created a small snippet which illustrates my problem:
http://jsfiddle.net/wgwLcgz6/1/
var jsonStr = JSON.stringify({ arg1: 'some string "with quotes"' });
$('#out1').html(jsonStr); // {"arg1":"some string \"with quotes\""}
JSON.parse(jsonStr); // Works just fine
try {
// Copied the ouput of JSON.stringify manually and pasted it directly into
// the parse function...
JSON.parse('{"arg1":"some string \"with quotes\""}');
// We never get here since an exception is thrown
$('#out2').html('Parsed successfully');
} catch (ex) {
// SyntaxError: Unexpected token w
$('#out2').html(ex.toString());
}
I think I do understand why this is happening even though I can't explain it properly but I don't have any idea on how to circumvent this and would really appreciate some help and maybe deeper explanation.
One more thing: If I paste the stringified object {"arg1":"some string \"with quotes\""} into an online json parser like http://jsonlint.com/ it parses it just fine which I guess is because they use there own parser instead of the browsers built in ones...
You need to escape quotes and backslashes. Since you're using single quotes around a string with double quotes, you just have to escape the backslashes:
JSON.parse('{"arg1":"some string \\"with quotes\\""}');