Currently been working on eliminating the excess "," comma on the json object I have below.
{"rules": {
"1000": {
"action": "2",
"category": "skype",
"entity": "Private",
"id": "1000",
},
"1200": {
"action": "2",
"category": "http",
"entity": "Public",
"id": "1200",
},
"100": {
"action": "2",
"category": "ftp",
"entity": "Public",
"id": "100",
},
"0": {
"entity": "Private",
"category": "alcohol, tobacco",
"action": "1",
"id": "low",
},
"3000": {
} }}
Maybe you have some insights on what's the cleanest way to eliminate it using AngularJS.
The data was parsed from this code snippet.
var request = {
url: 'sample/uri',
method: "GET",
transformResponse: specialTransform
};
var response = $q.defer( );
$http( request ).success( function( THIS DATA -> data, status ) {
eval
var fixTrailingCommas = function (jsonString) {
var jsonObj;
eval('jsonObj = ' + jsonString);
return JSON.stringify(jsonObj);
};
fixTrailingCommas('{"rules": { "1000": { "action": "2", "category": "skype", "entity": "Private", "id": "1000" , } } }');
Please use eval here only if you completely trust incoming json, and also be aware of other eval evils as described on MDN and its note on JSON parsing
Note that since JSON syntax is limited compared to JavaScript syntax, many valid JavaScript literals will not parse as JSON. For example, trailing commas are not allowed in JSON, and property names (keys) in object literals must be enclosed in quotes. Be sure to use a JSON serializer to generate strings that will be later parsed as JSON.
You may also choose to rely on implementation of JSON2 by Douglas Crockford which uses eval internally
On current browsers, this file does nothing,
preferring the built-in JSON object. There is no reason to use this file unless
fate compels you to support IE8, which is something that no one should ever
have to do again.
But because we really need to use this library, we have to make few code modifications, e.g. simply comment out JSON type check, which will then override native browser object (or we may also introduce new JSON2 global variable)
//if (typeof JSON !== 'object') {
JSON = {};
//}
P.S. Other parsing fuctions json_parse.js and json_parse_state.js, which don't use eval, throw a syntax error
Angular part
var config = {
transformResponse: function (data, headers) {
if(headers("content-type") === "application/json" && angular.isString(data)) {
try {
data = JSON.parse(data);
} catch (e) {
// if parsing error, try another parser
// or just fix commas, if you know for sure that the problem is in commas
data = JSON2.parse(data);
}
return data;
} else {
return data;
}
}
};
$http.get("rules.json", config).success(function (data) {
$scope.rules = data;
});
So as you said, the JSON is wrongly generated on the server you are taking it from, can you change the way it is generated there? (Follow this: Can you use a trailing comma in a JSON object?)
In case you are unable to do so, you need to use something like mentioned here:
Can json.loads ignore trailing commas?
library to repair a JSON object, like: https://www.npmjs.com/package/jsonrepair
(try some online fix tool here: http://www.javascriptformat.com/)
or some regexp magic
Related
I'm using Laravel 5.4 for an api and have an endpoint that accepts JSON along the lines of:
{
"input": {
"owner": "name of owner",
"content": [
]
}
}
I want to get only the JSON inside input and ensure that it is valid, both structurally and based on the content.
Using http://json-guard.thephpleague.com and their basic example from the overview page, everything comes back as valid no matter what I change as the input so I assume I am using it wrong.
From their example I have constructed the following. It passes validation. The issue is that I cannot get it to fail.
routes file
Route::post('validate', 'TestController#validateJson');
TestController#validateJson
public function validateJson()
{
$dereferencer = \League\JsonReference\Dereferencer::draft4();
$schema = json_decode('{ "properties": { "id": { "type": "string", "format": "uri" } } }');
$data = json_decode('{ "id": "https://json-guard.dev/schema#" }');
$validator = new \League\JsonGuard\Validator($data, $schema);
if ($validator->fails()) {
return response($validator->errors());
}
return response('all ok');
}
I believe I might need to use the JSON Reference and define a custom schema, but until I can fully understand the example and get it to fail, I don't want to do anything more complicated.
everything comes back as valid no matter what I change as the input so I assume I am using it wrong.
It is hard to say exactly what the issue is without seeing an example of what input you tried. Since the example schema validates that id is a string with the uri format, it should fail when you provide a string that is not a valid URI. The following example will return a format error:
<?php
require __DIR__ . '/vendor/autoload.php';
$schema = json_decode('{ "properties": { "id": { "type": "string", "format": "uri" } } }');
$data = json_decode('{ "id": "hello world" }');
$validator = new \League\JsonGuard\Validator($data, $schema);
echo json_encode($validator->errors(), JSON_PRETTY_PRINT);
There are some parts of JSON Schema that are unintuitive and you might not expect to pass.
A constraint only validates if it applies to that type. If you don't pass an object validation will pass because the properties constraint only applies to objects:
$data = null;
var_dump((new \League\JsonGuard\Validator($data, $schema))->passes()); // true
To make non object inputs fail you need to specify "type": "object". Note that this will also happen with invalid JSON, since json_decode will return null when it fails.
Validation will also pass with an empty object:
$data = json_decode('{}');
var_dump((new \League\JsonGuard\Validator($data, $schema))->passes()); // true
To make the properties required you have to use the required keyword.
I want to get only the JSON inside input and ensure that it is valid, both structurally and based on the content.
This schema should work as a starting point:
{
"type": "object",
"properties": {
"input": {
"type": "object",
"properties": {
"owner": {
"type": "string",
"minLength": 1"
},
"content": {
"type": "array"
}
},
"required": ["owner", "content"],
"additionalProperties": false
}
},
"required": ["input"],
"additionalProperties": false
}
We are requiring that the input is an object, that it has an input property and no other properties, and that input is an object with the properties owner and content. The minLength rule on owner is to prevent an empty string from passing.
I believe I might need to use the JSON Reference and define a custom schema
You can write pretty complex schemas without using JSON Reference at all. It's just a way to reuse a schema without copy and pasting. For example, you might define a 'money' schema and use that for any dollar amounts in your API.
You definitely will need to write a custom schema. The schema replaces the Laravel validation rules you would write for each endpoint otherwise.
I am getting a JSON object from a webservice which after JSON.stringify().I am getting this output-`
[
{
"user": "A220",
"shorttext": "shanghai",
"reportedBy": "S,A",
"questions": "[{\"question\":\"Q1\",\"is_mand\":\"0\",\"type\":\"text\",\"answer\":\"w\",\"ansYesOrNo\":false,\"ansDetails\":\"\"},{\"question\":\"Q2\",\"is_mand\":\"0\",\"type\":\"text\",\"answer\":\"ed\",\"ansYesOrNo\":false,\"ansDetails\":\"\"}]",
"notifno": "20143995",
"error": "",
"createdOn": "2015-09-09 13:08:36",
"Id": 0,
"$$hashKey": "object:89"
}
]
`
I want to remove all these back slash.
I tried using
var a=JSON.stringify(<that object>).replace(/\\/g, "");
But its giving result as a form string that too INVALID like this-
[
{
"user": "A220",
"shorttext": "shanghai",
"reportedBy": "S,A",
"questions": "[{"question":"Q1","is_mand":"0","type":"text","answer":"w","ansYesOrNo":false,"ansDetails":""},{"question":"Q2","is_mand":"0","type":"text","answer":"ed","ansYesOrNo":false,"ansDetails":""}]",
"notifno": "20143995",
"error": "",
"createdOn": "2015-09-09 13:08:36",
"Id": 0,
"$$hashKey": "object:89"
}
]
My only objective is to remove the back slash without changing the data type.
I want to access the first question of questions.
Its not working...
JsFiddle link-LINK
You dont need to do JSON.stringify() in web service response. You can directly work like
$http.get('/someUrl').
then(function(response)
{
$scope.data = response;
},
function(response)
{
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Now you have print in html like {{data}}
You can use this method to remove backslash from a JSON string
var data = {"\\id\\":"\\23232\\","\\pass\\":"\\1434\\"};
console.log(data);
var b=JSON.stringify(data);
str = b.replace(/\\/g, '');
console.log(str);
I want to decode in extjs4 with Ext.decode(string), a json string with json string inside, just like this:
var string = "{success:true,
rows:[{"jsonfields":"[
{\\"name\\":\\"cm:title\\",\\"title\\":\\"Titolo\\",\\"description\\":\\"Titolo del contenuto\\",\\"dataType\\":\\"d:mltext\\",\\"url\\":\\"\/api\/property\/cm_title\\"},
{\\"name\\":\\"cm:content\\",\\"title\\":\\"Contenuto\\",\\"description\\":\\"Contenuto\\",\\"dataType\\":\\"d:content\\",\\"url\\":\\"\/api\/property\/cm_content\\"},
{\\"name\\":\\"cm:name\\",\\"title\\":\\"Nome\\",\\"description\\":\\"Nome\\",\\"dataType\\":\\"d:text\\",\\"url\\":\\"\/api\/property\/cm_name\\"}]"}
]}";
As you can see "jsonfields" is a json string code.
How I can decode this string with Ext.decode(string)
Any suggests?
There were a couple of problems with your JSON code.
All of your keys needed to be in quotes (success and rows were not).
Use single quotes when embedding a JSON string directly into javascript. This way you can avoid using the escape character.
Below is the correct JSON code. I have also updated your jsfiddle link.
var string = '{
"success": true,
"rows": [
{
"jsonfields": [
{
"name": "cm: title",
"title": "Titolo",
"description": "Titolodelcontenuto",
"dataType": "d: mltext",
"url": "/api/property/cm_title"
},
{
"name": "cm: content",
"title": "Contenuto",
"description": "Contenuto",
"dataType": "d: content",
"url": "/api/property/cm_content"
},
{
"name": "cm: name",
"title": "Nome",
"description": "Nome",
"dataType": "d: text",
"url": "/api/property/cm_name"
}
]
}
]}';
var decodedString = Ext.decode(string);
console.log(decodedString);
That's the correct way to decode JSON with Ext and the exception is likely telling you about some invalid syntax in your JSON string. The JSON format is very strict.
You can use an online validator like jsonlint to help figure out what's wrong with your syntax.
One other note: in cases like this, it's usually easier to use single quotes around your string so that you can embed double-quotes without having to escape them.
var string = '{ "success": true, ...}'
jQuery Code:
$(document).ready(function(){
$.getJSON('dat.js', function(data) {
var obj = JSON.parse(data);
alert(obj[0].title);
});
});
My JSON file :
{
"posts":
[
{
"title": "ajax | Programming ",
"url": "hello"
},
{
"title": "jQuery and Ajax Demos Pard - 3",
"url": "how are you"
},
]
}
Its giving me an error JSON.parse:unexpected character. But when I tried to do it by taking the json inside an array its ok then. I want to access the data from json file itself
you do parseJSON when your input is a json string and u expect an object. Here, getJSON is already giving u the response as an object.
try this
$(document).ready(function(){
$.getJSON('dat.js', function(obj) {
alert(obj.posts[0].title);
});
});
A Quick jslint check says that you have invalid json at line 11 },, Try removing the comma from the last member of "posts" and see if that help
{
"title": "jQuery and Ajax Demos Pard - 3",
"url": "how are you"
}, <---- THIS
I got problem. I have this JSON automatically generated by Open Flash Chart php library. The problem is, OFC report JSON Parse Error [Syntax Error] while test result using http://www.jsonlint.com/ report that my JSON is fine. But, w3c parser report error too:(
Any help?
Here's the JSON:
{
"title": "Followers Trend",
"elements": [
{
"type": "area_hollow",
"fill-alpha": 0.35,
"values": [
],
"colour": "#5B56B6",
"text": "Followers",
"font-size": 12
}
],
"x_axis": {
"colour": "#A2ACBA",
"grid-colour": "#D7E4A3",
"offset": false,
"steps": 4,
"labels": {
"steps": 2,
"rotate": "vertical",
"colour": "#A2ACBA",
"labels": [
]
}
},
"x_legend": {
"text": "Week Trend (2009-08-17 - 2009-08-24)",
"style": "{font-size: 20px; color: #778877}"
},
"y_axis": {
"min": 0,
"max": 150,
"steps": 30
}
}
A few things I learned while playing with JSON is:
If you have validate the JSON on various JSON validation services and the result is GOOD. But, when you failed to eval it, try to wrap your JSON using ( and ) => ({jsondata})
var json = eval( "(" + jsonString + ")" );
NEVER build the JSON yourself. It's a gate to failure. Always use official or popular JSON library (depending on your language). For example:
On PHP: use json_encode()
On Java Android: use org.json.JSONObject
A list of all other available library to play with JSON is listed in JSON official page.
To display and format JSON data, you can use JSONViewer.
I think the w3c parser is having issues, I couldn't even get it to parse this:
{
"title" : "Followers Trend"
}
It gave me this error:
Validation errors:
lexer couldn't parse at "{
"title" : "Followers Trend"
}"
http://json.bloople.net helps you visualise the code to find and correct errors.
try this code, JSON.parse() method is not able to handle string which is in a
single quote as a value in the right-hand side. also if you want to handle the
UTF-8 character code, then it will do.
parseJSON = function() {
var data = {};
var reader = new FileReader();
reader.onload = function() {
try {
data = JSON.parse(reader.result.replace(/'/g, "\""));
console.log(data)
} catch (ex) {
console.log('error' + ex);
}
};
reader.readAsText(fileSelector_test[0].files[0], 'utf-8');
}