How to check if it's a string or json [duplicate] - javascript

This question already has answers here:
How to test if a string is JSON or not?
(22 answers)
Closed 3 years ago.
I have a json string that is converted from object by JSON.Stringify function.
I'd like to know if it's json string or just a regular string.
Is there any function like "isJson()" to check if it's json or not?
I'd like to use the function when I use local storage like the code below.
Thank you in advance!!
var Storage = function(){}
Storage.prototype = {
setStorage: function(key, data){
if(typeof data == 'object'){
data = JSON.stringify(data);
localStorage.setItem(key, data);
} else {
localStorage.setItem(key, data);
}
},
getStorage: function(key){
var data = localStorage.getItem(key);
if(isJson(data){ // is there any function to check if the argument is json or string?
data = JSON.parse(data);
return data;
} else {
return data;
}
}
}
var storage = new Storage();
storage.setStorage('test', {x:'x', y:'y'});
console.log(storage.getStorage('test'));

The "easy" way is to try parsing and return the unparsed string on failure:
var data = localStorage[key];
try {return JSON.parse(data);}
catch(e) {return data;}

you can easily make one using JSON.parse. When it receives a not valid JSON string it throws an exception.
function isJSON(data) {
var ret = true;
try {
JSON.parse(data);
}catch(e) {
ret = false;
}
return ret;
}

Found this in another post How do you know if an object is JSON in javascript?
function isJSON(data) {
var isJson = false
try {
// this works with JSON string and JSON object, not sure about others
var json = $.parseJSON(data);
isJson = typeof json === 'object' ;
} catch (ex) {
console.error('data is not JSON');
}
return isJson;
}

Since the question is "How to check if it's a string or json" maybe a simple way would be to check for string, so you would have done something like this somewhere:
if (typeof data === 'string') { // check for string!
//... do something
} else {///... do something else}
Maybe that could be enough depending on your overall solution, just in case someone else is looking around.

I think returning parsed JSON at the same time is a good idea, so I prefer following version:
function tryParse(str) {
try {
return { value: JSON.parse(str), isValid: true }
} catch (e) {
return { value: str, isValid: false }
}
}
As you probably know JSON.parse("1234"), JSON.parse("0"), JSON.parse("false") and JSON.parse("null") won't raise Exception and will return true. all this values are valid JSON but if you want to see isValid is true only for objects (e.g: { "key": "value" }) and arrays (e.g: [{ "key": "value" }]) you can use following version:
function tryParse(str) {
try {
var parsed = JSON.parse(str);
return { value: parsed , isValid: typeof parsed === 'object'}
} catch (e) {
return { value: str, isValid: false }
}
}

Related

JSON object and string function

I am trying to call startsWith() string function on a JSON property value:
{"message":"xyzabc"}
var jsonResponse = JSON.parse(httpResponse.text);
var stringMessage = jsonResponse.message.toString();
if(stringMessage.startsWith('xyz')) {
...
}
but I get the error:
Object xyzabc has no method 'startsWith'
How can I do that?
The code is running on server side, Express on Node.js
It may be happen that your browser does not support the startsWith() function so you can use use the RegExp to overcame this problem like this...
var jsonObject={message:"xyzHELLO"};
var regex=new RegExp("^xyz");
if(regex.test(jsonObject["message"])){
alert("hello");
}
Live Demo HERE
[EDIT]
If you want to add the function startsWith() in your each and every string than you can add like this
if (String.prototype.startsWith !== "function") {
String.prototype.startsWith = function (searching) {
var regex = new RegExp("^" + searching);
if (regex.test(this.toString())) {
return true;
}
else {
return false;
}
}
}
and after that you can use like this:
var jsonObject = { message: "xyzHELLO" };
if (jsonObject["message"].toString().startsWith("xyz")) {
alert("start with");
}
else {
alert("not start with");
}
[EDIT]
if (String.prototype.startsWith !== "function") {
String.prototype.startsWith = function (searching) {
if (this.toString().indexOf(searching) == 0) {
return true;
}
else {
return false;
}
}
}
As per the comment by #nnnnnn and I also think it is good practice if we use the native function of the JavaScript, Thanks #nnnnnn.
Please double check your input JSON. Your code works like a charm with a correct JSON input in httpResponse.text.
var json = '{"message": "xyztest"}';
var jsonResponse = JSON.parse(json);
var stringMessage = jsonResponse.message.toString();
if(stringMessage.startsWith('xyz')) {
alert('It works!');
}
Also please make sure the browser you are working in supports startsWith method. Here you can find a list with all supported browsers.
If you need to work around the browser compatibility issues, you can use the widely supported indexOf method.
if(stringMessage.indexOf('xyz') === 0) {
alert('It works!');
}
HERE is a Fiddle for both cases.
Apparently, Js has startsWith function for the strings. However, using your own function to see if the string starts with the value should cause no error.
function StartsWith(s1, s2) {
return (s1.length >= s2.length && s1.substr(0, s2.length) == s2);
}
var jsonResponse = JSON.parse(httpResponse.text);
var stringMessage = jsonResponse.message.toString();
if(StartsWith(stringMessage,'xyz')) {
//Doing Stuff!
}

$.parseJSON(resp); if resp is number it works

I was using this to test if server returned data is json.
try {
json = $.parseJSON(resp);
} catch (error) {
json = null;
}
if (json) {
//
} else {
//
}
But it returns true if resp is a number lik 2 or 3 or... It returns null if resp is 0.
Any ideas how to avoid this false situation?
I'm outputting data using php:
echo 0; //returns null
echo 2; //returns as valid json
It appears, 0 is read as string, and 2 is read as number.
If you're expecting an integer, use parseInt:
try {
val = parseInt(resp, 10);
if(val > 0) /* act accordingly ... */
} catch (error) {
val = null;
}
If you want to know if the "JSON is valid," you can use something akin to the following:
function isValidJSON(string){
try {
$.parseJSON(string);
return true;
}
catch(e){ return false; }
}
I suggest something like:
// source from Angular source
function isJson(data) {
return (/^\s*[\[\{]/.test(data) && /[\}\]]\s*$/.test(data));
};
So...
if (isJson(resp))
json = $.parseJSON(resp);
else
alert ('another response: ' + resp);
Numbers like 2 or 3 are technically valid JSON data. Do you expect an object? See e.g. this SO post for methods of checking if the returned variable is an object.
Basically your workflow would be to try to parse it as JSON, and if it succeeds, check if it's an object/list (depending on what you expect).
Example:
try {
json = $.parseJSON(resp);
return (typeof(json) === "object")
} catch (error) {
json = null;
}

Programs with Javascript json parsing

I am trying to parse a json object and try to do an alert in js if a particular word is detected in the json string,
CloudPush.addEventListener('callback', function (evt) {
//alert(evt);
alert(evt.payload);
var jsonNotification = JSON.parse(evt.payload);
for (var i = 0; i < jsonNotification.length; i++) {
var text = new String(jsonNotification[i]);
if (text == 'Hello') {
alert('Hello');
}else{
alert('Error');
}
}
I am however getting some errors that the alert 'Hello' does not display. Not really sure if I am doing it correctly. Hopefully someone can shed some light.
CloudPush.addEventListener('callback',
function (evt) {
// parse the desired data
var data= JSON.parse(evt.payload),
key;
// loop over all the keys of the JSON object
for (key in data) {
if(data.hasOwnProperty(key)){
alert( data[key] === 'Hello' ? 'Hello' : 'Error' );
}
}
);

How to test if a string is JSON or not?

I have a simple AJAX call, and the server will return either a JSON string with useful data or an error message string produced by the PHP function mysql_error(). How can I test whether this data is a JSON string or the error message.
It would be nice to use a function called isJSON just like you can use the function instanceof to test if something is an Array.
This is what I want:
if (isJSON(data)){
//do some data stuff
}else{
//report the error
alert(data);
}
Use JSON.parse
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
This code is JSON.parse(1234) or JSON.parse(0) or JSON.parse(false) or JSON.parse(null) all will return true.
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
So I rewrote code in this way:
function isJson(item) {
item = typeof item !== "string"
? JSON.stringify(item)
: item;
try {
item = JSON.parse(item);
} catch (e) {
return false;
}
if (typeof item === "object" && item !== null) {
return true;
}
return false;
}
Testing result:
isJson test result
Let's recap this (for 2019+).
Argument: Values such as true, false, null are valid JSON (?)
FACT: These primitive values are JSON-parsable but they are not well-formed JSON structures. JSON specification indicates JSON is built on on two structures: A collection of name/value pair (object) or an ordered list of values (array).
Argument: Exception handling shouldn't be used to do something expected.
(This is a comment that has 25+ upvotes!)
FACT: No! It's definitely legal to use try/catch, especially in a case like this. Otherwise, you'd need to do lots of string analysis stuff such as tokenizing / regex operations; which would have terrible performance.
hasJsonStructure()
This is useful if your goal is to check if some data/text has proper JSON interchange format.
function hasJsonStructure(str) {
if (typeof str !== 'string') return false;
try {
const result = JSON.parse(str);
const type = Object.prototype.toString.call(result);
return type === '[object Object]'
|| type === '[object Array]';
} catch (err) {
return false;
}
}
Usage:
hasJsonStructure('true') // —» false
hasJsonStructure('{"x":true}') // —» true
hasJsonStructure('[1, false, null]') // —» true
safeJsonParse()
And this is useful if you want to be careful when parsing some data to a JavaScript value.
function safeJsonParse(str) {
try {
return [null, JSON.parse(str)];
} catch (err) {
return [err];
}
}
Usage:
const [err, result] = safeJsonParse('[Invalid JSON}');
if (err) {
console.log('Failed to parse JSON: ' + err.message);
} else {
console.log(result);
}
If the server is responding with JSON then it would have an application/json content-type, if it is responding with a plain text message then it should have a text/plain content-type. Make sure the server is responding with the correct content-type and test that.
When using jQuery $.ajax() the response will have the responseJSON property if the response was JSON, this can be tested like this:
if (xhr.hasOwnProperty('responseJSON')) {}
I use just 2 lines to perform that:
var isValidJSON = true;
try { JSON.parse(jsonString) } catch { isValidJSON = false }
That's all!
But keep in mind there are 2 traps:
1. JSON.parse(null) returns null
2. Any number or string can be parsed with JSON.parse() method.
JSON.parse("5") returns 5
JSON.parse(5) returns 5
Let's some play on code:
// TEST 1
var data = '{ "a": 1 }'
// Avoiding 'null' trap! Null is confirmed as JSON.
var isValidJSON = data ? true : false
try { JSON.parse(data) } catch(e) { isValidJSON = false }
console.log("data isValidJSON: ", isValidJSON);
console.log("data isJSONArray: ", isValidJSON && JSON.parse(data).length ? true : false);
Console outputs:
data isValidJSON: true
data isJSONArray: false
// TEST 2
var data2 = '[{ "b": 2 }]'
var isValidJSON = data ? true : false
try { JSON.parse(data2) } catch(e) { isValidJSON = false }
console.log("data2 isValidJSON: ", isValidJSON);
console.log("data2 isJSONArray: ", isValidJSON && JSON.parse(data2).length ? true : false);
Console outputs:
data2 isValidJSON: true
data2 isJSONArray: true
// TEST 3
var data3 = '[{ 2 }]'
var isValidJSON = data ? true : false
try { JSON.parse(data3) } catch(e) { isValidJSON = false }
console.log("data3 isValidJSON: ", isValidJSON);
console.log("data3 isJSONArray: ", isValidJSON && JSON.parse(data3).length ? true : false);
Console outputs:
data3 isValidJSON: false
data3 isJSONArray: false
// TEST 4
var data4 = '2'
var isValidJSON = data ? true : false
try { JSON.parse(data4) } catch(e) { isValidJSON = false }
console.log("data4 isValidJSON: ", isValidJSON);
console.log("data4 isJSONArray: ", isValidJSON && JSON.parse(data4).length ? true : false);
Console outputs:
data4 isValidJSON: true
data4 isJSONArray: false
// TEST 5
var data5 = ''
var isValidJSON = data ? true : false
try { JSON.parse(data5) } catch(e) { isValidJSON = false }
console.log("data5 isValidJSON: ", isValidJSON);
console.log("data5 isJSONArray: ", isValidJSON && JSON.parse(data5).length ? true : false);
Console outputs:
data5 isValidJSON: false
data5 isJSONArray: false
// TEST 6
var data6; // undefined
var isValidJSON = data ? true : false
try { JSON.parse(data6) } catch(e) { isValidJSON = false }
console.log("data6 isValidJSON: ", isValidJSON);
console.log("data6 isJSONArray: ", isValidJSON && JSON.parse(data6).length ? true : false);
Console outputs:
data6 isValidJSON: false
data6 isJSONArray: false
var parsedData;
try {
parsedData = JSON.parse(data)
} catch (e) {
// is not a valid JSON string
}
However, I will suggest to you that your http call / service should return always a data in the same format. So if you have an error, than you should have a JSON object that wrap this error:
{"error" : { "code" : 123, "message" : "Foo not supported" } }
And maybe use as well as HTTP status a 5xx code.
I like best answer but if it is an empty string it returns true. So here's a fix:
function isJSON(MyTestStr){
try {
var MyJSON = JSON.stringify(MyTestStr);
var json = JSON.parse(MyJSON);
if(typeof(MyTestStr) == 'string')
if(MyTestStr.length == 0)
return false;
}
catch(e){
return false;
}
return true;
}
There are probably tests you can do, for instance if you know that the JSON returned is always going to be surrounded by { and } then you could test for those characters, or some other hacky method. Or you could use the json.org JS library to try and parse it and test if it succeeds.
I would however suggest a different approach. Your PHP script currently returns JSON if the call is successful, but something else if it is not. Why not always return JSON?
E.g.
Successful call:
{ "status": "success", "data": [ <your data here> ] }
Erroneous call:
{ "status": "error", "error": "Database not found" }
This would make writing your client side JS much easier - all you have to do is check the "status" member and the act accordingly.
Well... It depends the way you are receiving your data. I think the server is responding with a JSON formated
string (using json_encode() in PHP,e.g.). If you're using JQuery post and set response data to be a JSON format and it is a malformed JSON, this will produce an error:
$.ajax({
type: 'POST',
url: 'test2.php',
data: "data",
success: function (response){
//Supposing x is a JSON property...
alert(response.x);
},
dataType: 'json',
//Invalid JSON
error: function (){ alert("error!"); }
});
But, if you're using the type response as text, you need use $.parseJSON. According jquery site:
"Passing in a malformed JSON string may result in an exception being thrown". Thus your code will be:
$.ajax({
type: 'POST',
url: 'test2.php',
data: "data",
success: function (response){
try {
parsedData = JSON.parse(response);
} catch (e) {
// is not a valid JSON string
}
},
dataType: 'text',
});
Here is a code with some minor modification in Bourne's answer.
As JSON.parse(number) works fine without any exception so added isNaN.
function isJson(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return isNaN(str);
}
All json strings start with '{' or '[' and end with the corresponding '}' or ']', so just check for that.
Here's how Angular.js does it:
var JSON_START = /^\[|^\{(?!\{)/;
var JSON_ENDS = {
'[': /]$/,
'{': /}$/
};
function isJsonLike(str) {
var jsonStart = str.match(JSON_START);
return jsonStart && JSON_ENDS[jsonStart[0]].test(str);
}
https://github.com/angular/angular.js/blob/v1.6.x/src/ng/http.js
I think something like following method should do the job, it returns the parsed JSON (in case of valid JSON), so you don't need to call the JSON.parse again.
const tryParseJSON = (s) => {
if (!s) return false;
try {
var o = JSON.parse(s);
if (o && typeof o === "object") return o;
}
catch (e) { }
return false;
};
You could try decoding it and catching the exception (native or json2.js):
try {
newObj = JSON.parse(myJsonString);
} catch (e) {
console.log('Not JSON');
}
However, I would suggest making the response always be valid JSON. If you get an error back from your MySQL query, simply send back JSON with the error:
{"error":"The MySQL error string."}
And then:
if (myParsedJSON.error) {
console.log('An error occurred: ' + myParsedJSON.error);
}
I used this one (kind of mix of different answers, but anyway):
const isJSON = str => {
if (typeof str === 'string'){
try {
JSON.parse(str)
return true
} catch(e){
}
}
return false
}
[null, undefined, false, true, [], {},
'', 'asdf', '{}', '[]', "{\"abc\": 2}","{\"abc\": \"2\"}"]
.map(el => {
console.log(`[>${el}<] - ${isJSON(el)}`)
})
console.log('-----------------')
Warning: For methods relying on JSON.parse - Arrays and quote surrounded strings will pass too (ie. console.log(JSON.parse('[3]'), JSON.parse('"\uD800"')))
To avoid all non-object JSON primitives (boolean, null, array, number, string), I suggest using the following:
/* Validate a possible object ie. o = { "a": 2 } */
const isJSONObject = (o) =>
!!o && (typeof o === 'object') && !Array.isArray(o) &&
(() => { try { return Boolean(JSON.stringify(o)); } catch { return false } })()
/* Validate a possible JSON object represented as string ie. s = '{ "a": 3 }' */
function isJSONObjectString(s) {
try {
const o = JSON.parse(s);
return !!o && (typeof o === 'object') && !Array.isArray(o)
} catch {
return false
}
}
Code Explanation
!!o - Not falsy (excludes null, which registers as typeof 'object')
(typeof o === 'object') - Excludes boolean, number, and string
!Array.isArray(o) - Exclude arrays (which register as typeof 'object')
try ... JSON.stringify / JSON.parse - Asks JavaScript engine to determine if valid JSON
Why not use the hasJsonStructure() answer?
Relying on toString() is not a good idea. This is because different JavaScript Engines may return a different string representation. In general, methods which rely on this may fail in different environments or may be subject to fail later should the engine ever change the string result
Why is catching an exception not a hack?
It was brought up that catching an exception to determine something's validity is never the right way to go. This is generally good advice, but not always. In this case, exception catching is likely is the best route because it relies on the JavaScript engine's implementation of validating JSON data.
Relying on the JS engine offers the following advantages:
More thorough and continually up-to-date as JSON spec changes
Likely to run faster (as it's lower level code)
When given the opportunity to lean on the JavaScript engine, I'd suggest doing it. Particularly so in this case. Although it may feel hacky to catch an exception, you're really just handling two possible return states from an external method.
You can try the following one because it also validates number, null, string but the above-marked answer is not working correctly it's just a fix of the above function:
function isJson(str) {
try {
const obj = JSON.parse(str);
if (obj && typeof obj === `object`) {
return true;
}
} catch (err) {
return false;
}
return false;
}
For me I simply did this just by 2 positive returned condition,
First Condition - Check if the both ends are "{" and "}"
Second Condition - Check if it is parsable by JSON
here how I did it
const isJsonStringified = (value) => {
try {
const isObject = value.slice(0, 1) === '{' && value.slice(value.length - 1) === '}';
if (typeof value === 'string' && isObject) {
JSON.parse(value);
} else {
return false;
}
} catch (err) {
return false;
}
return true;
};
Welcome :)
If you don't mind lodash
npm i -S lodash
const isPlainObject = require("lodash/isPlainObject"); // cjs
// import {isPlainObject} from "lodash"; // esm
function checkIfJSON(input) {
const inputStr = typeof input === "string" ? input : JSON.stringify(input);
try {
if (isPlainObject(JSON.parse(inputStr))) {
return true;
}
} catch (e) {
return false;
}
}
Numbers and boolean values are accepted as valid json in JSON.parse(), just add type validations before parsing
function isJson(str) {
if(!isNaN(str) || str.toString() == 'true' || str.toString() == 'false'){
return false;
}
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
export function isJsonString(value) {
try {
return typeof JSON.parse(value) === 'object';
} catch (e) {
return false;
}
}
This handled most of the required cases for me!
In addition to previous answers, in case of you need to validate a JSON format like "{}", you can use the following code:
const validateJSON = (str) => {
try {
const json = JSON.parse(str);
if (Object.prototype.toString.call(json).slice(8,-1) !== 'Object') {
return false;
}
} catch (e) {
return false;
}
return true;
}
Examples of usage:
validateJSON('{}')
true
validateJSON('[]')
false
validateJSON('')
false
validateJSON('2134')
false
validateJSON('{ "Id": 1, "Name": "Coke" }')
true

How to check if a string is a valid JSON string?

isJsonString('{ "Id": 1, "Name": "Coke" }')
should be true and
isJsonString('foo')
isJsonString('<div>foo</div>')
should be false.
I'm looking for a solution that doesn't use try/catch because I have my debugger set to "break on all errors" and that causes it to break on invalid JSON strings.
Use a JSON parser like JSON.parse:
function isJsonString(str) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
I know i'm 3 years late to this question, but I felt like chiming in.
While Gumbo's solution works great, it doesn't handle a few cases where no exception is raised for JSON.parse({something that isn't JSON})
I also prefer to return the parsed JSON at the same time, so the calling code doesn't have to call JSON.parse(jsonString) a second time.
This seems to work well for my needs:
/**
* If you don't care about primitives and only objects then this function
* is for you, otherwise look elsewhere.
* This function will return `false` for any valid json primitive.
* EG, 'true' -> false
* '123' -> false
* 'null' -> false
* '"I'm a string"' -> false
*/
function tryParseJSONObject (jsonString){
try {
var o = JSON.parse(jsonString);
// Handle non-exception-throwing cases:
// Neither JSON.parse(false) or JSON.parse(1234) throw errors, hence the type-checking,
// but... JSON.parse(null) returns null, and typeof null === "object",
// so we must check for that, too. Thankfully, null is falsey, so this suffices:
if (o && typeof o === "object") {
return o;
}
}
catch (e) { }
return false;
};
A comment first. The question was about not using try/catch.
If you do not mind to use it, read the answer below.
Here we just check a JSON string using a regexp, and it will work in most cases, not all cases.
Have a look around the line 450 in https://github.com/douglascrockford/JSON-js/blob/master/json2.js
There is a regexp that check for a valid JSON, something like:
if (/^[\],:{}\s]*$/.test(text.replace(/\\["\\\/bfnrtu]/g, '#').
replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
//the json is ok
}else{
//the json is not ok
}
EDIT: The new version of json2.js makes a more advanced parsing than above, but still based on a regexp replace ( from the comment of #Mrchief )
// vanillaJS
function isJSON(str) {
try {
return (JSON.parse(str) && !!str);
} catch (e) {
return false;
}
}
Usage: isJSON({}) will be false, isJSON('{}') will be true.
To check if something is an Array or Object (parsed JSON):
// vanillaJS
function isAO(val) {
return val instanceof Array || val instanceof Object ? true : false;
}
// ES2015
var isAO = (val) => val instanceof Array || val instanceof Object ? true : false;
Usage: isAO({}) will be true, isAO('{}') will be false.
Here my working code:
function IsJsonString(str) {
try {
var json = JSON.parse(str);
return (typeof json === 'object');
} catch (e) {
return false;
}
}
I used a really simple method to check a string how it's a valid JSON or not.
function testJSON(text){
if (typeof text!=="string"){
return false;
}
try{
var json = JSON.parse(text);
return (typeof json === 'object');
}
catch (error){
return false;
}
}
Result with a valid JSON string:
var input='["foo","bar",{"foo":"bar"}]';
testJSON(input); // returns true;
Result with a simple string;
var input='This is not a JSON string.';
testJSON(input); // returns false;
Result with an object:
var input={};
testJSON(input); // returns false;
Result with null input:
var input=null;
testJSON(input); // returns false;
The last one returns false because the type of null variables is object.
This works everytime. :)
In prototypeJS, we have method isJSON. You can try that. Even json might help.
"something".isJSON();
// -> false
"\"something\"".isJSON();
// -> true
"{ foo: 42 }".isJSON();
// -> false
"{ \"foo\": 42 }".isJSON();
// -> true
Here is the typescript version too:
JSONTryParse(input: any) {
try {
//check if the string exists
if (input) {
var o = JSON.parse(input);
//validate the result too
if (o && o.constructor === Object) {
return o;
}
}
}
catch (e: any) {
}
return false;
};
isValidJsonString - check for valid json string
JSON data types - string, number, object (JSON object), array, boolean, null
(https://www.json.org/json-en.html)
falsy values in javascript - false, 0, -0, 0n, ", null, undefined, NaN
- (https://developer.mozilla.org/en-US/docs/Glossary/Falsy)
JSON.parse
works well for number , boolean, null and valid json String won't raise any error. please refer example below
JSON.parse(2) // 2
JSON.parse(null) // null
JSON.parse(true) // true
JSON.parse('{"name":"jhamman"}') // {name: "jhamman"}
JSON.parse('[1,2,3]') // [1, 2, 3]
break when you parse undefined , object, array etc
it gave Uncaught SyntaxError: Unexpected end of JSON input . please refer example below
JSON.parse({})
JSON.parse([])
JSON.parse(undefined)
JSON.parse("jack")
function isValidJsonString(jsonString){
if(!(jsonString && typeof jsonString === "string")){
return false;
}
try{
JSON.parse(jsonString);
return true;
}catch(error){
return false;
}
}
From Prototype framework String.isJSON definition here
/**
* String#isJSON() -> Boolean
*
* Check if the string is valid JSON by the use of regular expressions.
* This security method is called internally.
*
* ##### Examples
*
* "something".isJSON();
* // -> false
* "\"something\"".isJSON();
* // -> true
* "{ foo: 42 }".isJSON();
* // -> false
* "{ \"foo\": 42 }".isJSON();
* // -> true
**/
function isJSON() {
var str = this;
if (str.blank()) return false;
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '#');
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
return (/^[\],:{}\s]*$/).test(str);
}
so this is the version that can be used passing a string object
function isJSON(str) {
if ( /^\s*$/.test(str) ) return false;
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '#');
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
return (/^[\],:{}\s]*$/).test(str);
}
function isJSON(str) {
if ( /^\s*$/.test(str) ) return false;
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '#');
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
return (/^[\],:{}\s]*$/).test(str);
}
console.log ("this is a json", isJSON( "{ \"key\" : 1, \"key2#e\" : \"val\"}" ) )
console.log("this is not a json", isJSON( "{ \"key\" : 1, \"key2#e\" : pippo }" ) )
Maybe it will useful:
function parseJson(code)
{
try {
return JSON.parse(code);
} catch (e) {
return code;
}
}
function parseJsonJQ(code)
{
try {
return $.parseJSON(code);
} catch (e) {
return code;
}
}
var str = "{\"a\":1,\"b\":2,\"c\":3,\"d\":4,\"e\":5}";
alert(typeof parseJson(str));
alert(typeof parseJsonJQ(str));
var str_b = "c";
alert(typeof parseJson(str_b));
alert(typeof parseJsonJQ(str_b));
output:
IE7: string,object,string,string
CHROME: object,object,string,string
This answer to reduce the cost of trycatch statement.
I used JQuery to parse JSON strings and I used trycatch statement to handle exceptions, but throwing exceptions for un-parsable strings slowed down my code, so I used simple Regex to check the string if it is a possible JSON string or not without going feather by checking it's syntax, then I used the regular way by parsing the string using JQuery :
if (typeof jsonData == 'string') {
if (! /^[\[|\{](\s|.*|\w)*[\]|\}]$/.test(jsonData)) {
return jsonData;
}
}
try {
jsonData = $.parseJSON(jsonData);
} catch (e) {
}
I wrapped the previous code in a recursive function to parse nested JSON responses.
I think I know why you want to avoid that. But maybe try & catch !== try & catch. ;o) This came into my mind:
var json_verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};
So you may also dirty clip to the JSON object, like:
JSON.verify = function(s){ try { JSON.parse(s); return true; } catch (e) { return false; }};
As this as encapsuled as possible, it may not break on error.
I am way too late to the party. This is what I ended up doing.
Using a quick regex pre-check improves performs by a big margin
if(/^\s*(\{|\[)/.test(str)){
try{
JSON.parse(str)
// do something here, or return obj/true
}catch(e){
// do nothing or return false
}
}
The regex will check if string opens with a [ or {.
This will eliminate most false cases (not all).
Here is a quick performance test for you https://jsbench.me/awl6fgn8jb/1
Worst case this can be 10-15% slower than using try directly, worst case meaning all strings are valid json string.
Best case this is 99% faster than pure try, best case meaning all strings are non-valid json.
function get_json(txt)
{ var data
try { data = eval('('+txt+')'); }
catch(e){ data = false; }
return data;
}
If there are errors, return false.
If there are no errors, return json data
You can use the javascript eval() function to verify if it's valid.
e.g.
var jsonString = '{ "Id": 1, "Name": "Coke" }';
var json;
try {
json = eval(jsonString);
} catch (exception) {
//It's advisable to always catch an exception since eval() is a javascript executor...
json = null;
}
if (json) {
//this is json
}
Alternatively, you can use JSON.parse function from json.org:
try {
json = JSON.parse(jsonString);
} catch (exception) {
json = null;
}
if (json) {
//this is json
}
Hope this helps.
WARNING: eval() is dangerous if someone adds malicious JS code, since it will execute it. Make sure the JSON String is trustworthy, i.e. you got it from a trusted source.
Edit For my 1st solution, it's recommended to do this.
try {
json = eval("{" + jsonString + "}");
} catch (exception) {
//It's advisable to always catch an exception since eval() is a javascript executor...
json = null;
}
To guarantee json-ness. If the jsonString isn't pure JSON, the eval will throw an exception.
var jsonstring='[{"ConnectionString":"aaaaaa","Server":"ssssss"}]';
if(((x)=>{try{JSON.parse(x);return true;}catch(e){return false}})(jsonstring)){
document.write("valide json")
}else{
document.write("invalide json")
}
I infer from the opening comment that the use case is delineating whether a response is HTML or JSON. In which case, when you do receive JSON, you probably ought to be parsing it and handling invalid JSON at some point in your code anyway. Aside from anything, I imagine you would like to be informed by your browser should JSON be expected but invalid JSON received (as will users by proxy of some meaningful error message)!
Doing a full regex for JSON is unnecessary therefore (as it would be - in my experience - for most use-cases). You would probably be better off using something like the below:
function (someString) {
// test string is opened with curly brace or machine bracket
if (someString.trim().search(/^(\[|\{){1}/) > -1) {
try { // it is, so now let's see if its valid JSON
var myJson = JSON.parse(someString);
// yep, we're working with valid JSON
} catch (e) {
// nope, we got what we thought was JSON, it isn't; let's handle it.
}
} else {
// nope, we're working with non-json, no need to parse it fully
}
}
that should save you having to exception handle valid non-JSON code and take care of duff json at the same time.
if(resp) {
try {
resp = $.parseJSON(resp);
console.log(resp);
} catch(e) {
alert(e);
}
}
hope this works for you too
I thought I'd add my approach, in the context of a practical example. I use a similar check when dealing with values going in and coming out of Memjs, so even though the value saved may be string, array or object, Memjs expects a string. The function first checks if a key/value pair already exists, if it does then a precheck is done to determine if value needs to be parsed before being returned:
function checkMem(memStr) {
let first = memStr.slice(0, 1)
if (first === '[' || first === '{') return JSON.parse(memStr)
else return memStr
}
Otherwise, the callback function is invoked to create the value, then a check is done on the result to see if the value needs to be stringified before going into Memjs, then the result from the callback is returned.
async function getVal() {
let result = await o.cb(o.params)
setMem(result)
return result
function setMem(result) {
if (typeof result !== 'string') {
let value = JSON.stringify(result)
setValue(key, value)
}
else setValue(key, result)
}
}
The complete code is below. Of course this approach assumes that the arrays/objects going in and coming out are properly formatted (i.e. something like "{ key: 'testkey']" would never happen, because all the proper validations are done before the key/value pairs ever reach this function). And also that you are only inputting strings into memjs and not integers or other non object/arrays-types.
async function getMem(o) {
let resp
let key = JSON.stringify(o.key)
let memStr = await getValue(key)
if (!memStr) resp = await getVal()
else resp = checkMem(memStr)
return resp
function checkMem(memStr) {
let first = memStr.slice(0, 1)
if (first === '[' || first === '{') return JSON.parse(memStr)
else return memStr
}
async function getVal() {
let result = await o.cb(o.params)
setMem(result)
return result
function setMem(result) {
if (typeof result !== 'string') {
let value = JSON.stringify(result)
setValue(key, value)
}
else setValue(key, result)
}
}
}
If you're dealing with a response from an AJAX (or XMLHttpRequest) call, what worked for me is to check the response content type and parse or not the content accordingly.
Just keeping it simple
function isValidJsonString(tester) {
//early existing
if(/^\s*$|undefined/.test(tester) || !(/number|object|array|string|boolean/.test(typeof tester)))
{
return false;
};
//go ahead do you parsing via try catch
return true;
};
Oh you can definitely use try catch to check whether its or not a valid JSON
Tested on Firfox Quantom 60.0.1
use function inside a function to get the JSON tested and use that output to validate the string. hears an example.
function myfunction(text){
//function for validating json string
function testJSON(text){
try{
if (typeof text!=="string"){
return false;
}else{
JSON.parse(text);
return true;
}
}
catch (error){
return false;
}
}
//content of your real function
if(testJSON(text)){
console.log("json");
}else{
console.log("not json");
}
}
//use it as a normal function
myfunction('{"name":"kasun","age":10}')
The function IsJsonString(str), that is using JSON.parse(str), doesn't work in my case.
I tried to validate json output from GraphiQL it always return false. Lucky me, isJSON works better:
var test = false;
$('body').on('DOMSubtreeModified', '.resultWrap', function() {
if (!test) {
var resultWrap = "{" + $('#graphiql .resultWrap').text().split("{").pop();
if isJSON(resultWrap) {test = !test;}
console.log(resultWrap);
console.log(resultWrap.isJSON());
}
});
Sample output:
THREE.WebGLRenderer 79
draw.js:170 {xxxxxxxxxx​
draw.js:170 false
draw.js:170 {xxxxxxxxxx ​
draw.js:170 false
draw.js:170 {xxxxxxxxxx ​
draw.js:170 false
draw.js:170 {xxxxxxxxxx ​
draw.js:170 false
draw.js:170 {​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,  "width": 396.984,​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,  "width": 396.984,  "height": 327​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,  "width": 396.984,  "height": 327}​
draw.js:170 false
draw.js:170 {  "PI": 3.141592653589793,  "time": 1570751209006,  "tick": 156,  "tickr": 1.56,  "fps": 41.666666666666664,  "width": 396.984,  "height": 327}
draw.js:170 true
For people who like the .Net convention of "try" functions that return a boolean and handle a byref param containing the result. If you don't need the out parameter you can omit it and just use the return value.
StringTests.js
var obj1 = {};
var bool1 = '{"h":"happy"}'.tryParse(obj1); // false
var obj2 = {};
var bool2 = '2114509 GOODLUCKBUDDY 315852'.tryParse(obj2); // false
var obj3 = {};
if('{"house_number":"1","road":"Mauchly","city":"Irvine","county":"Orange County","state":"California","postcode":"92618","country":"United States of America","country_code":"us"}'.tryParse(obj3))
console.log(obj3);
StringUtils.js
String.prototype.tryParse = function(jsonObject) {
jsonObject = jsonObject || {};
try {
if(!/^[\[{]/.test(this) || !/[}\]]$/.test(this)) // begin / end with [] or {}
return false; // avoid error handling for strings that obviously aren't json
var json = JSON.parse(this);
if(typeof json === 'object'){
jsonObject.merge(json);
return true;
}
} catch (e) {
return false;
}
}
ObjectUtils.js
Object.defineProperty(Object.prototype, 'merge', {
value: function(mergeObj){
for (var propertyName in mergeObj) {
if (mergeObj.hasOwnProperty(propertyName)) {
this[propertyName] = mergeObj[propertyName];
}
}
return this;
},
enumerable: false, // this is actually the default
});
If you don't want to do try/catch anywhere, looking for a single liner, and don't mind using async functions:
const isJsonString = async str => ( await ((async v => JSON.parse(v))(str)).then(_ => true).catch(_ => false) );
await isJsonString('{ "Id": 1, "Name": "Coke" }'); // true
await isJsonString('foo'); // false
await isJsonString('<div>foo</div>'); // false
if you have a doubt the value is or not json
function isStringified(jsonValue) { // use this function to check
try {
console.log("need to parse");
return JSON.parse(jsonValue);
} catch (err) {
console.log("not need to parse");
return jsonValue;
}
}
and then
const json = isStringified(stringValue);
if (typeof json == "object") {
console.log("string is a valid json")
}else{
console.log("string is not a valid json")
}

Categories