JSON Parser error - javascript

I am using the json parser from json.org to handle data from my application. The problem is that the parser cannot handle some json formats.
One request receives the data below.
<?php
$obj = array("cities"=>array("city1","city2","city3","city4","city5"));
echo json_encode($obj);
?>
Results in the json below
{
"cities": ["city1","city2","city3","city4","city5"]
}
the code below handles the above data
var data = json_parse(XMLHttpRequestObject.responseText, function (key, value){
alert(key +' = '+value);
});
The parser fails and throws an error.
Does anyone know how to handle such an object.

I executed the following for a quick test and it seems to work:
var text = '{ "cities": ["city1","city2","city3","city4","city5"] }';
var data = json_parse(text, function (key, value){
document.write(key + ' = ' + value + '<br/>');
});
document.write('result = ' + data);
It recursively walks the structure and the result is this:
0 = city1
1 = city2
2 = city3
3 = city4
4 = city5
cities = ,,,,
= [object Object]
result = undefined
What is in your XMLHttpRequestObject.responseText field?
Also, aren't you supposed to return a value from your function(key, value)?

You need to put your keys and values into double quotes:
{
"cities": ["city1","city2","city3","city4","city5"]
}
A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.
You can use jsonlint to validate the code.

I'd wager that the problem lies in your data. The '' before city3 is wrong.
It would help if you include some information on the error thrown.

The parser fails because the JSON data is malformed. There are two quotes in front of city3 and the starting quote for city4 is missing.
{
cities: ['city1','city2','city3','city4','city5']
}
Are you in control of the code that generates this output? It looks like it's being built by hand, while if possible it should be generated using a JSON library.
PHP example:
$output = array(
'cities' => array('city1', 'city2', 'city3', 'city4', 'city5')
);
echo json_encode($output);
Output:
{"cities":["city1","city2","city3","city4","city5"]}

The problem seems to be in your application's json encoding algorithm.
Since you did't specify the application language, I cannot tell you the exact function/method to use, but I suggest you to use standard json encoding techniques instead reinventing the wheel.
For example in php you can use the json_encode standard function of one of the many encoding libraries in the open source world.

Related

Generating fully valid JSON with client-side JavaScript

So I am trying to create a JSON explorer / editor. I am able to parse the initial JSON into the div and format it how I like.
this is the function i use to loop through the initial JSON
_iterate(_tab, raw_json){
var tab = _tab;
tab++;
for(var key1 in raw_json){
var data_type = typeof raw_json[key1];
var d = String(raw_json[key1])
if(d == String){
d = "String";
}
if(d == Number){
d= "Number"
}
if(data_type == "object" || data_type == "array"){
this.input.append(`<json-tab tab-width="${tab}"></json-tab><div class="json-editor-input-container-2 -je-${data_type}">'<span class="-je-key">${key1}</span>' :{</div></br>`)
this._iterate(tab, raw_json[key1])
}else{
this.input.append(`<div class="json-editor-row"><json-tab tab-width="${tab}"></json-tab><div class="json-editor-input-container-2">'<span class="-je-key">${key1}<span>' : '<div class="json-editor-input -je-${data_type}" contenteditable="true" for="{key: '${key1}', data: '${d}'}"></div>', </div></br></div>`)
}
}
this.input.append(`<json-tab tab-width="${tab -1}"></json-tab>},</br>`)
}
in order to save the JSON I was going to retrieve the JSON from the text of the div using
getJSON(){
var json_text = this.input.text().slice(0, -1)
return JSON.parse(`"${json_text}"`)
}
right now this is able to be parse by JSON.parse(); but when i want to console.log(getJSON()[0]) this returns {
am i not formating the JSON correctly. a live example of this can be found here
First, your console.log result doesn't make sense. A parsed JSON object is now usable in JavaScript and, if has (only) properties x and y, would result in undefined when requesting property 0 as you have. It looks like your call to console.log was to a different (earlier?) version of the getJSON() function, where it returned the raw string, and in that case it makes sense that you're just retrieving the first character of the JSON text: "{".
But then, assuming the version of getJSON() as written, it would actually throw a parse exception:
VM1511:1 Uncaught SyntaxError: Unexpected token ' in JSON at position 1
Looking at your site, I was able to do, in the console:
jsonString = $('json-editor').text()
// value: "{'partName' : '', 'partRevision' : '', ..."
That is illegal JSON. JSON specifies (only) the quotation mark " for strings (Unicode/ASCII 0x22) on page 7 of its specification.
The fact that 'partName' is legal as a JavaScript string literal is irrelevant but perhaps confusing.
As a minor style point, simplify JSON.parse(`"${json_text}"`) to JSON.parse(json_text).
#BaseZen's answer was very helpful for me to understand what was going wrong with my code. My JSON was incorrectly formatted even though online linters say its correct. Along with what BaseZen pointed out, JSON.parse() will not work with trailing commas. To fix this:
_remove_trailing_commas(json_string){
var regex = /\,(?!\s*?[\{\[\"\'\w])/g;
return json_string.replace(regex, '');
}
I found this information at SO post JSON Remove trailiing comma from last object
SO user Dima Parzhitsky's answer was what helped me also figure out this question.

JSON.Parse,'Uncaught SyntaxError: Unexpected token o [duplicate]

This question already has answers here:
I keep getting "Uncaught SyntaxError: Unexpected token o"
(9 answers)
Closed 6 years ago.
I am having trouble with JSON returned from a web service. It looks like the JSON lacks quotes, but when I add quotes to the JSON, I get an error. Here is the error message: 'Uncaught SyntaxError: Unexpected token o. When I log the string to console:[object Object],[object Object]
Here is some example code that simulates the error:
//Error I am trying to solve
var jsonString = '[{"Id":"10","Name":"Matt"},{"Id":"1","Name":"Rock"}]';
var myData = JSON.parse(jsonString);
$(document).ready(function() {
var $grouplist = $('#groups');
$.each(myData, function() {
$('<li>' + this.Name + '</li>').appendTo($grouplist);
});
});
Here is the same code with the single quotes around the string. It works
//Successful Javascript
var jsonString = '[{"Id":"10","Name":"Matt"},{"Id":"1","Name":"Rock"}]';
var myData = JSON.parse(jsonString);
$(document).ready(function() {
var $grouplist = $('#groups');
$.each(myData, function() {
$('<li>' + this.Name + '</li>').appendTo($grouplist);
});
});
//Successful HTML
<ul id="groups"></ul>
But when I try to add quotes to the string, like I seem to need to in my real code, it fails:
//Does not work when I need to append quotes to the string:
var jsonStringNoQuotes = [{"Id":"10","Name":"Matt"},{"Id":"1","Name":"Rock"}];
jsonStringQuotes = "'" + jsonStringNoQuotes + "'";
var myData = JSON.parse(jsonStringQuotes);
$(document).ready(function() {
var $grouplist = $('#groups');
$.each(myData, function() {
$('<li>' + this.Name + ',' + this.Id + '</li>').appendTo($grouplist);
});
});
Here is the error:
log string to console:[object Object],[object Object]
data.js:809 Uncaught SyntaxError: Unexpected token '
I'm stumped. Any help appreciated! Thank you!
Without single quotes around it, you are creating an array with two objects inside of it. This is JavaScript's own syntax. When you add the quotes, that object (array+2 objects) is now a string. You can use JSON.parse to convert a string into a JavaScript object. You cannot use JSON.parse to convert a JavaScript object into a JavaScript object.
//String - you can use JSON.parse on it
var jsonStringNoQuotes = '[{"Id":"10","Name":"Matt"},{"Id":"1","Name":"Rock"}]';
//Already a javascript object - you cannot use JSON.parse on it
var jsonStringNoQuotes = [{"Id":"10","Name":"Matt"},{"Id":"1","Name":"Rock"}];
Furthermore, your last example fails because you are adding literal single quote characters to the JSON string. This is illegal. JSON specification states that only double quotes are allowed. If you were to console.log the following...
console.log("'"+[{"Id":"10","Name":"Matt"},{"Id":"1","Name":"Rock"}]+"'");
//Logs:
'[object Object],[object Object]'
You would see that it returns the string representation of the array, which gets converted to a comma separated list, and each list item would be the string representation of an object, which is [object Object]. Remember, associative arrays in javascript are simply objects with each key/value pair being a property/value.
Why does this happen? Because you are starting with a string "'", then you are trying to append the array to it, which requests the string representation of it, then you are appending another string "'".
Please do not confuse JSON with Javascript, as they are entirely different things. JSON is a data format that is humanly readable, and was intended to match the syntax used when creating javascript objects. JSON is a string. Javascript objects are not, and therefor when declared in code are not surrounded in quotes.
See this fiddle:
http://jsfiddle.net/NrnK5/
var jsonStringNoQuotes = [{"Id":"10","Name":"Matt"},{"Id":"1","Name":"Rock"}];
it will create json object. no need to parse.
jsonStringQuotes = "'" + jsonStringNoQuotes + "'";
will return '[object]'
thats why it(below) is causing error
var myData = JSON.parse(jsonStringQuotes);
Your last example is invalid JSON. Single quotes are not allowed in JSON except inside strings. In the second example, the single quotes are not in the string, but serve to show the start and end.
See http://www.json.org/ for the specifications.
Should add: Why do you think this: "like I seem to need to in my real code"? Then maybe we can help you come up with the solution.
Maybe what comes from the server is already evaluated as JSON object? For example, using jQuery get method:
$.get('/service', function(data) {
var obj = data;
/*
"obj" is evaluated at this point if server responded
with "application/json" or similar.
*/
for (var i = 0; i < obj.length; i++) {
console.log(obj[i].Name);
}
});
Alternatively, if you need to turn JSON object into JSON string literal, you can use JSON.stringify:
var json = [{"Id":"10","Name":"Matt"},{"Id":"1","Name":"Rock"}];
var jsonString = JSON.stringify(json);
But in this case I don't understand why you can't just take the json variable and refer to it instead of stringifying and parsing.

Javascript replace for equal symbol

I am getting my response as following
var val = {"Type"=>"D","Number"=>33"}
From above i try to change like this
var MyArray = {"Type": "D", "Number": "33"};
for(key in MyArray)
{
alert("key " + key
+ " has value "
+ MyArray[key]);
}
I tried replace, replace all but those not working. Any suggestions?
Server side code pasted from comments...
new_transfer_header = #params['my_extra_param']
p new_transfer_header,'------------ ew_transfer_header----------,new_transfer_header.class
WebView.execute_js("replaceDeliveryWithScanUnit('#{new_transfer_header}')")
puts result as "{\"Type\"=>\"D\", \"Number\"=>\"33\"}
var val = {"Type"=>"D","Number"=>33"}
Is invalid JavaScript - there is no way to fix it within the same script/script block since it fails parsing.
Likely you need to eliminate extra HTML encoding that somone done for this chunk of script on the server.
If it is text received by some AJAX call you should be able to replace " and similar values with corresponding characters and than parse with JSON.parse.
you could use string.replace and cal eval on the result I think, but would it be better to get valid json from the server ?

Parsing malformed JSON with Javascript

I want to parse this content using Javascript. The data looks like this:
{"ss":[["Thu","7:00","Final",,"BAL","19","ATL","20",,,"56808",,"PRE4","2015"],["Thu","7:00","Final",,"NO","10","GB","38",,,"56809",,"PRE4","2015"]]}
Every single tutorial online teaches you how to parse JSON using Twitter, but I am not quite sure how parsing with JSON works.
I would like to set this up on a website to view the NFL team scores for a fun project and a good learning experience about parsing JSON, as I could care less about Twitter stuff.
Is this possible? Any good tutorials to start with? Even some starting code?
Generally speaking, you can use JSON.parse to do this. However, that snippet that you have does not appear to be strictly valid JSON (as seen here: http://jsfiddle.net/yK3Gf/ and also by validating the source JSON here: http://jsonlint.com/).
So you will either need to parse it by hand, or get nfl.com to fix up their JSON.
As an alternative, their JSON does parse successfully when using eval(), so you could parse it with something like:
var parsedData = eval('(' + jsonData + ')');
...as shown here: http://jsfiddle.net/yK3Gf/1/
Though be aware that parsing JSON in this way is generally frowned upon (particularly when the data being parsed is being delivered by a third-party source), as it leaves you open to XSS attacks should the data happen to include any executable code inside of it.
I am in a similar position - non javascript expert working on a fun project to familiarize myself with javascript, ajax, and json.
I took three different steps to handle the problem. I welcome any feedback on improving the solution.
The first step is to query the nfl site to pull down the scores. Because the source of the json, the nfl site, is different from your site, you will have to work around the javascript security constraints against cross domain querying. I found this stackoverflow link to be a good reference. I used JSONP for the workaround. I used http://whateverorigin.org/ as the indirection site.
$.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent('http://www.nfl.com/liveupdate/scorestrip/scorestrip.json') + '&callback=?', handleQueryForScoresResult);
As others have pointed out, the nfl site returns invalid json data. The following sample line illustrates the problem:
["Sun","4:25","Final",,"TEN","7","MIN","30",,,"55571",,"REG5","2012"],
Notice the empty array element values (the repeated commas with no data in between). So in my json callback function, I corrected the data by adding empty strings (two double quotes) to repeated commas before calling jquery to parse the json data:
function handleQueryForScoresResult(data) {
var jsonStr = data.contents;
jsonStr = jsonStr.replace(/,,/g, ',"",');
jsonStr = jsonStr.replace(/,,/g, ',"",');
var scoresData = jQuery.parseJSON(jsonStr).ss;
.
.
.
}
Lastly, I created GameScores object to encapsulate the json data.
function GameScore(scoreData) {
this.scoreData = scoreData;
scoreData[2] = scoreData[2].toLowerCase();
scoreData[5] = parseInt(scoreData[5]);
scoreData[7] = parseInt(scoreData[7]);
}
function GameScore_getAwayTeam() { return this.scoreData[4]; }
function GameScore_getHomeTeam() { return this.scoreData[6]; }
function GameScore_isFinal() { return this.scoreData[2]=="final"; }
function GameScore_getHomeTeamScore() { return this.scoreData[7]; }
function GameScore_getAwayTeamScore() { return this.scoreData[5]; }
function GameScore_doesHomeTeamLead() { return this.scoreData[7]> this.scoreData[5]; }
function GameScore_doesAwayTeamLead() { return this.scoreData[5]> this.scoreData[7]; }
function GameScore_getWeekId() { return this.scoreData[12]; }
GameScore.prototype.getHomeTeam = GameScore_getHomeTeam;
GameScore.prototype.getAwayTeam = GameScore_getAwayTeam;
GameScore.prototype.isFinal = GameScore_isFinal;
GameScore.prototype.getHomeTeamScore = GameScore_getHomeTeamScore;
GameScore.prototype.getAwayTeamScore = GameScore_getAwayTeamScore;
GameScore.prototype.doesHomeTeamLead = GameScore_doesHomeTeamLead;
GameScore.prototype.doesAwayTeamLead = GameScore_doesAwayTeamLead;
GameScore.prototype.getWeekId = GameScore_getWeekId;
I only added a few accessors as I did not need most of the data. Your needs may vary.
We are using mootools for stuff like that, but you can do it it plain JavaScript as well: http://www.json.org/js.html.
Let's assume you already have a valid JSON String (jsonString) to parse. (If you don't know how to retrieve a String to parse using XMLHttpRequest from the given url you will have to look into that first.)
With plain JavaScript you will have to add Douglas Crockford's JSON library (or something similar) in order to provide a parsing Function if there is no native implementation:
var json = json_parse(jsonString) ;
link
With a JavaScript library like jQuery this would be
var json = $.parseJSON(jsonString) ;
Now, traversing the resultant JSON Object is a whole other issue, because you will have to know its structure before you can retrieve specific data.
In this particular case -- if it was indeed well formed -- you would have to do the following:
var data = json.ss ;
for(var i = 0 ; i < data.length ; i++) {
var entry = data[i] ;
var day = entry[0] ; //!! the Arrays seem to have a format where the first entry always contains the data and so forth...
/* ... */
// then do something with the data bits
}
Your main problem is that fact that the JSON your pulling in is malformed or not valid according to RFC 4627.
What you can do is grab the copy the JSON data and format it using this tool http://www.freeformatter.com/json-formatter.html
After you have the formatted version then you can use the jQuery ajax call
$.ajax({
url: "your-formatted.json",
dataType: 'json',
success: function (data) {
for (var i = 0; i < data.ss.length; i++) {
document.write("Day: " + data.ss[i][0]);
document.write("<br/>");
document.write("Time: " + data.ss[i][1]);
document.write("<br/><br/>");
}
}
});
You shouldn't actually use document.write in your application. This is only for example purpose of displaying the data.
For this specific issue (the empty indexes within the arrays from the JSON response) I did a regex replacement with a lookahead assertion. Considering that request contains the XMLHttpRequest:
request.responseText.replace(/,(?=,)/gm, ",\"\"")
This will turn ,, into ,"", and will also work in case there are more commas in sequence, so ,,, becomes ,"","",. You can use JSON.parse() afterwards.
This malformed JSON can be parsed by the dirty-json NPM package (I am the author).
You can test a demo of the parser here: https://rmarcus.info/dirty-json
The parser interprets the JSON in your original question as equivalent to the following valid JSON:
{
"ss": [
[
"Thu",
"7:00",
"Final",
"BAL",
"19",
"ATL",
"20",
"56808",
"PRE4",
"2015"
],
[
"Thu",
"7:00",
"Final",
"NO",
"10",
"GB",
"38",
"56809",
"PRE4",
"2015"
]
]
}

How do I convert a JSON string to a function in javascript?

How can I convert a string in javascript/jquery to a function?
I am trying to use a JSON parameter list to initialize a function. However, one of the parameters is a function, which I store as a string, and I get an error when I try to use eval() to return the function.
For example, if my JSON is:
json = { "one": 700, "two": "function(e){alert(e);}" }
Then in my code:
parameters = eval(json);
$('myDiv').addThisFeature({
parameter_1: json.one,
parameter_2: eval(json.two) // <= generates error
})
Example: http://jsfiddle.net/patrick_dw/vs83H/
var json = '{ "one": 700, "two": "function(e){alert(e);}" }';
var parameters = JSON.parse( json );
eval( 'var func = ' + parameters.two );
func( 'test' ); // alerts "test"
You'll need to load the JSON library in browsers that don't support it.
Or do two separate evals:
Example: http://jsfiddle.net/patrick_dw/vs83H/1/
var json = '{ "one": 700, "two": "function(e){alert(e);}" }';
eval( 'var parameters = ' + json );
eval( 'var func = ' + parameters.two );
func( 'test' );
I assume you're aware of the dangers of eval.
Looking for a way to not use eval this is the best I could come up with. Use the Function constructor to create a function from a string.
var parsed = JSON.parse('{"one":"700", "two":"function(){return 0;}" }');
var func = new Function('return ' + parsed.two)(); // return parsed.two function
alert(typeof func); // function
alert(func()) // 0
Use this:
parameters = eval('(' + json + ')');
$('#myDiv').addThisFeature({
parameter_1: parameters.one,
parameter_2: eval('(' + parameters.two + ')') // <= does not generate an error
});
Adding the parentheses at the beginning and end of the string prevents the syntax error.
Note, however, that you are parsing JSON using eval (which in some cases has security risks, but I assume that is irrelevant because you do want to run arbitrary code sent by the server). If you have the server-side flexibility (to send invalid JSON), you could just send the function not quoted as a string and eval should be able to parse that just fine.
See this SO question. As was said, JSON is meant to hold data. To treat a piece of the data as a function, you would first need to eval the string.
You are eval'ing an anonymous function, which of course won't be called by anything. If you really wanted to run the code in the json then the text would need to be alert(e).
However it doesn't sound like a very sensible thing to do. You'd be better off writing code to deal with the contents of the json object, rather than trying to run code embedded in the json.
Neither way is particularly nice, but if you can get rid of the function(e) wrapper bits, then you can use var myDynamicFunction = new Function("e", "alert(e);"); Otherwise, you're looking at using eval(). Eval() is evil in general. If this is JSON that you're getting back from a $.getJSON call or something, you're opening yourself up to security concerns.

Categories

Resources