JSON to JavaScript, SyntaxError: Unexpected token & - javascript

I know this question has been asked numerous times, but I really donĀ“t get it.
I am creating a site in MVC, and I'm creating a JSON string from my model. I then want to pass it as argument to a JavaScript function that uses it to plot a graph.
Here is were I create the JSON string. This indeed creates a valid JSON string, I checked it at JSONLint.
#{
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var weightsAsJsonString = serializer.Serialize(Enumerable.Select(Model, weight =>
new
{
date = weight.Date,
value = weight.Value
}));
}
Further down I create a JavaScript variable from it and pass it into the JavaScript function:
var jsonStringToGraph = #weightsAsJsonString;
google.setOnLoadCallback(drawVisualization(jsonstring));
When I run this, the console prints 'SyntaxError: Unexpected token &' at the line were I declare jsonStringToGraph. I googled around and concluded that I should put ' ' around #weightsAsJsonString, so I do that.
Anyway, in my drawVisualization, I do this:
function drawVisualization(teststring) {
.......
var parsedJson = JSON.parse(teststring);
This gives me SyntaxError: Unexpected token & Index:1
I know that the code at the bottom is what is causing the exception, but I do not understand why. Do anyone understand what I am doing wrong?
Edit: This is the weightsAsJsonString
[{"date":"\/Date(1434492000000)\/","value":100.2},{"date":"\/Date(1434578400000)\/","value":99.2},{"date":"\/Date(1434664800000)\/","value":101.2},{"date":"\/Date(1434751200000)\/","value":98.2},{"date":"\/Date(1434837600000)\/","value":97.2},{"date":"\/Date(1434924000000)\/","value":96.2},{"date":"\/Date(1435010400000)\/","value":95.2},{"date":"\/Date(1435096800000)\/","value":94.2}]

It sounds like your issue is trying to inject content via Razor into JavaScript. By default # will HTML-encode your content, which doesn't work in the context of JavaScript.
#Html.Raw(weightsAsJsonString) will work better, and then your JS will have a JavaScript object, so there's no need for the JSON.parse later on.

When you do var jsonStringToGraph = #weightsAsJsonString; you are actually defining a JSON object and not a JSON string.
Hence when you do JSON.parse(teststring); you are trying to parse an object instead of a string.
Either put apostrophes around the first declaration var jsonStringToGraph = '#weightsAsJsonString'; or simply do not try to parse it again.

Related

Converting a .txt file into a JSON in Adobe Acrobat and how to reference it

I have a file attached to my PDF entitled JSONTEST.txt. I have successfully returned a string from that .txt, however, I am now trying to turn that string into a JSON so I can reference it as so (obj[key] returns key value). In reading, it seems like eval() is what I should be using, however, every time I do, it gives me this error:
SyntaxError: missing ; before statement
5:Document-Level:jsontest
This is the script I am using:
console.show(); console.clear();
var oFile = this.getDataObjectContents("JSONTEST.txt");
var cFile = util.stringFromStream(oFile, "utf-8");
var obj = eval(cFile);
What am I doing wrong?
Once it is working, can I reference it as I have described above?
I think I figured it out, though I'm still trying to figure out the correct way to reference fields. My JSON text was within curly brackets ( {} ), but should've been within square brackets ( [] ). Simple as that, so I change it to:
var obj = eval('[' + cFile + ']');
It seems to work now.

JS parse object wrapped in a string using same quotes as object keys

Consider the following event payload data returned via WS:
{
id: "1",
foo: "{"bar":"baz"}"
}
The current output of JSON.stringify(event.foo):
"{\"bar\":\"baz\"}"
Also consider the backend have no real way to return the foo value formatted differently and I need to find a way to parse the string associated to this foo key in order to access it's value of bar.
The identified problem is the fact that the quotes used to wrap the whole supposed object are the sames used in the object itself, resulting in making JSON.parse() impossible.
I'm wondering if there is a "clean" way to achieve this.
So far, I tried:
using JSON.parse() which fails due to the format of the string raising Unexpected end of JSON input
trimming external quotes and converting inner ones to single then parsing, results in same error.
using new Object(...) based on the string (trimmed of external quotes)
replacing all quotes with single ones and wrapping it again in double ones to parse it.
Any input appreciated
The problem here is the backend should really be fixed, but some reason you can not do it. Next issue is you can "fix it" on the front end, but you are putting a band aid on the problem and it will fall off when the data that comes back is not what you expect. So the solutions will be error prone unless you know the data coming back will be a specific type.
With this said, you can fix the invalid JSON that you have in your simple example with a couple of regular expressions. Problem is, if your data contains characters such as } in the text, this is going to fail.
var response = `
{
id: "1",
foo: "{"bar":"baz"}",
goo: "{"gar":"gaz"}"
}
`
var reObj = /"(\{[^}]*})"/
while (response.match(reObj)) {
response = response.replace(reObj, '$1')
}
var reKey = /^\s+(\S+):/m
while (response.match(reKey)) {
response = response.replace(reKey,'"$1":')
}
var obj = JSON.parse(response)
console.log(obj)

How to transform a Java object into a Javascript object?

In a jsp I use var accounts = ${sessionScope.allAccounts}; to get a Java list from session and transform it into a Javascript list. Then there is an error in Firebug:
SyntaxError: illegal character ... accounts =
[com.ailonger.po.Account#5aced6b4,
com.ailonger.po.Account#4171f1ff,...
It point out that the symbol'#' which causes the problem, but I think the symbol'#' is part of the addr. of the object. I don't know where do I make mistake or how to make the transition come true.
You could use json
This link shows how to encode java variables into json
https://www.tutorialspoint.com/json/json_java_example.htm
To decode into a JavaScript object use JSON.parse.
An example:
// myJson is the encoded json string
Var myNewObj=JSON.parse(myJson)

Correct JS parse of URL transmitted via JSON

Here's a simplified PHP side of my ajax context:
// in a for loop
$text = "/home/ubuntu/CANE-HDD-100/y.txt"
// $text_encoded = urlencode($text);
// $text_encoded = preg_replace("/(\-)/", "%2D", $text_encoded);
$text_encoded = "%2Fhome%2Fubuntu%2FCANE%2DHDD%2D100%2Fy.txt"
$structure[$i] = $text_encoded;
echo json_encode($structure);
And here is the JS side:
request.onload = function()
{
var cleanedText = JSON.parse(this.responseText);
alert(cleanedText);
};
That throws the following error:
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
If I substitute JSON.parse(this.responseText) with decodeURI(this.responseText), I get cleanedText equal to
/home/ubuntu/CANE-HDD-100/y.txt
["%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt"]
which I dislike, since an hypotetic for loop on cleanedText would treat every element of that variable (correctly) as a character, while I'd obviously like to get elements as whole URLs.
A possible, dirty workaround is to set up some regex on cleanedText to recover every URL, but I'm wondering if there would be a much cleaner way.
w3re's comment has to be correct. You must have malformed JSON. We can show this by taking the output you do get from decodeURI, running it back through encodeURI to get what must therefore be your original string from PHP, and then trying JSON.parse on it. We get an error:
JSON.parse(encodeURI('/home/ubuntu/CANE-HDD-100/y.txt ["%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt"]'))
(program):1 Uncaught SyntaxError: Unexpected token /
That error is from Chrome, but the :1 is saying 'line 1' and the / is at column 1, so I think that's the error you're seeing.
Basically, this string is not valid JSON, because of the all the stuff at the start which is not wrapped in quotes.
However, for example, this will work, if you put it all in quotes and escape the existing ones:
JSON.parse('"/home/ubuntu/CANE-HDD-100/y.txt \\"%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt\\""')
or using an array:
JSON.parse('["/home/ubuntu/CANE-HDD-100/y.txt", "%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt"]')
or an object:
JSON.parse('{"/home/ubuntu/CANE-HDD-100/y.txt": "%2Fhome%2Fubuntu%2FCANE-HDD-100%2Fy.txt"}')
so something must be going awry in your PHP or JavaScript in and amongst your JSON encoding and decoding. To help further, I'd need to see more of your code.

JSON from Newtonsoft to JavaScript

So, I have a some json data which I create in my controller like so:
Notes = JsonConvert.SerializeObject(contact.Notes.OrderBy(x => x.DateLogged).Select(x => new
{
id = x.Id,
date = x.DateLogged,
content = x.Content,
logged = x.Username
}))
This then gets passed to the view, now which statment can I do to achieve the results of having a variable contain that json data:
var data = '#Html.Raw(Model.Notes)'
or
var data = JSON.parse('#Html.Raw(Model.Notes)');
EDIT
the content variable holds some "\n" which when passed to the view using the first choice from above generates an error, saying
Unexpected Token
it only does it with \n so what is going wrong here? the bottom method doesn't quite work.
var data = JSON.parse('#Html.Raw(Model.Notes)');
This doesn't work - you can't put a JSON literal inside a JavaScript string. Any backslash in it will be an escape character to the JavaScript parser, not the JSON parser. A newline comes out like:
var data = JSON.parse('{"content": "abc\ndef"}');
which means the string you are asking JSON to parse is:
{"content": "abc
def"}
which is not valid as you can't have a literal newline in a JSON string.
To do this with JSON.parse you would have to JS-string-literal encode the JSON output, so you would end up with "abc\\ndef". The alternative would be to include the JSON directly in the script block as var data = #Html.Raw(Model.Notes);, but there are problems with this to do with the differences between JS and JSON (primarily characters U+2028 and U+2029) and the enclosing HTML context (ie what the sequence </script does).
Getting the escaping right here is harder than it looks, so you should avoid injecting anything into a <script> block. Better to put in-page JSON data in a data- attribute and read it from the DOM; this way you can use the normal HTML escaping Razor gives you by default.
<div id="notes" data-notes="#Model.Notes">
...
var data = JSON.parse(document.getElementById('notes').getAttribute('data-notes'));
bobince is obviously correct in what he says, it makes so much sense, thanks for that.
However, my solution was to simply do:
var data = #Html.Raw(Model.Notes);
Because, Newtonsoft already has converted it to a proper JSON format, so all it needs to do, is be assigned to a variable to be manipulated.
I think grabbing the content from a the HTML DOM is a bit too much for this.

Categories