309

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);
}
jeffery_the_wind
  • 17,048
  • 34
  • 98
  • 160
  • Possible duplicate of [AJAX: Check if a string is JSON?](https://stackoverflow.com/questions/2313630/ajax-check-if-a-string-is-json) – Mehdi Dehghani Mar 16 '19 at 06:22

22 Answers22

473

Use JSON.parse

function isJson(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
Bourne
  • 10,094
  • 5
  • 24
  • 51
  • 110
    Exception handling shouldn't be used to do something expected. – luisZavaleta Aug 31 '15 at 05:57
  • 117
    `JSON.parse(1234)` OR `JSON.parse(0)` OR `JSON.parse(false)` OR `JSON.parse(null)` all will not raise Exception and will return true !!. do not use this answer – Zalaboza Sep 12 '15 at 23:26
  • 30
    @Zalaboza `1234`, `0`, `false`, and `null` are all valid JSON values. If you want a predicate that tests if the JSON represents an object you'll need to do a little more. – Michael Lang Nov 18 '15 at 23:15
  • 32
    `JSON.parse` does a lot of computation to parse the string, and give you the json object if it succeeds, yet you're discarding the result which some users might want to use. That does not seem to be good. I'd instead `return {value: JSON.parse(str), valid: true};` and in the catch block `return {value: str, valid: false};`.. and I'd change the function name to `tryParse()`. – Nawaz Jun 08 '16 at 08:24
  • 1
    With ESLInt this fails as `try` should only be used in the rarest of occasions –  Jul 24 '17 at 05:11
  • 13
    @luisZavaleta then what do you suggest as a method – PirateApp Dec 26 '17 at 07:30
  • 1
    @MichaelLang, actually `1234` is __not__ valid JSON, `"1234"` is, `1234` is a __number__ (same for `0`, `false` and `null`) – Mehdi Dehghani Mar 17 '19 at 06:05
  • 1
    @luisZavaleta Generally, you're right. In this case, I would have to disagree. Using JSON.parse is simply relying on the JavaScript engine's routine for determining JSON validity, which is bound to be both more up to date and likely faster than any attempt to implement the same in higher level JavaScript code. – Ron S. Mar 20 '20 at 19:39
  • Please be aware that if you're not on a recent v8 version for whatever reason, using JSON.parse errors for control flow in this way will run into this memory leak: https://github.com/nodejs/node/issues/33266 – Tyler Gould Nov 04 '20 at 15:28
  • @MehdiDehghani https://datatracker.ietf.org/doc/html/rfc7159#section-6 – Kenneth K. Jul 12 '21 at 15:39
  • No, I understand how does @Mehdi understand it! And I think he has right! His logic is this: serialization converts a javascript data-only object to a **string**. Always to a string. Thus, it is logical that only and exclusively strings are back-convertable to a JSON. – peterh Jul 16 '21 at 18:14
  • However, that also an integer can be parsed as json (and gives itself back), also that is okay - Javascript, while it tries to be "typeless", it allows an automatic conversion to any number to a string. – peterh Jul 16 '21 at 18:15
  • Then also try checking/adding check for `typeof str === 'string'` as well – Anish Nair Sep 03 '21 at 11:42
  • @luisZavaleta says who? If we only used things for what they were intended/named for, we wouldn't be writing software in JavaScript in the first place. – Boris Verkhovskiy Mar 16 '22 at 11:04
136

Using JSON.parse() has some drawbacks:

  1. JSON.parse(1234) or
  2. JSON.parse(0) or
  3. JSON.parse(false) or
  4. JSON.parse(null)

all will return true.

function isJson(str) {
  try {
    JSON.parse(str);
  } catch (e) {
    return false;
  }  
  return true;
}

function testIsJson(value, expected) {
  console.log(`Expected: ${expected}, Actual: ${isJson(value)}`); 
}

// All of the following codes are expected to return false.
// But actually returns true.
testIsJson(1234, false);
testIsJson(0, false);
testIsJson(false, false);
testIsJson(null, false);

Code that handles false positives

So I rewrote code in this way:

function isJson(item) {
  let value = typeof item !== "string" ? JSON.stringify(item) : item;    
  try {
    value = JSON.parse(value);
  } catch (e) {
    return false;
  }
    
  return typeof value === "object" && value !== null;
}

Testing result:

function isJson(item) {
  let value = typeof item !== "string" ? JSON.stringify(item) : item;
  try {
    value = JSON.parse(value);
  } catch (e) {
    return false;
  }

  return typeof value === "object" && value !== null;
}

function testIsJson(value, expected) {
  console.log(`Expected: ${expected}, Actual: ${isJson(value)}`);
}

const validJson = { "foo": "bar" };
const notValidJson = '{ "foo": "bar" } invalid';

// expected: true
testIsJson(validJson, true);

// expected: false
testIsJson(1234, false);
testIsJson(0, false);
testIsJson(notValidJson, false);
testIsJson(false, false);
testIsJson(null, false);
kubosho_
  • 1,460
  • 1
  • 9
  • 9
93

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);
}
Onur Yıldırım
  • 32,327
  • 12
  • 84
  • 98
  • 1
    You link to the JSON Spec says the following: "A JSON text is a sequence of tokens formed from Unicode code points that conforms to the JSON value grammar." and "A JSON value can be an object, array, number, string, true, false, or null." - How did you arrive at the conclusion that a JSON can only be object or array at root level? I can't see this in the spec, nor anything regarding "well-formed JSON structures" – Relequestual Apr 16 '19 at 12:11
  • Read the second paragraph that starts with "JSON is built on two structures..." @ https://www.json.org or 4th and 5th paragraphs of http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf – Onur Yıldırım Apr 19 '19 at 00:38
  • 1
    json.org is informative only. Reading the spec you linked to doesn't support your suggestion. The spec mentions RFC 8259 as the latest RFC. Take a look at examples of valid JSON texs containing only values https://tools.ietf.org/html/rfc8259#section-13 - RFC 8259 is designed to resolve possible ambiguities and confusions, just like this. – Relequestual Apr 19 '19 at 18:25
  • 2
    Read the answer again. I'm saying values such as primitives (i.e. text values in the RFC examples) are not JSON "structure"s. There are no ambiguities. You CAN parse them as JSON, it's valid to do so. But they are not structured data. JSON is mainly invented as an interchange format » which is used for structured data » which can be an object or array. – Onur Yıldırım Apr 22 '19 at 23:29
  • 2
    OK, so I think we agree. Primatives are valid JSON according to the specification, but aren't "structures". That's fine. But, you said "Argument: Values such as true, false, null are valid JSON (?). Fact: Yes and no!" - The fact is the ARE valid JSON according to the specification. Opinions on if they are useful or not are irrelevant to that fact. – Relequestual Apr 23 '19 at 08:10
  • Relying on toString() is not a good idea, as different javascript engines may render the results differently. Unless I'm mistaken and toString() values are strictly regulated, I would highly recommend not using this solution. – Ron S. Mar 20 '20 at 19:32
  • If you test a .srt file (subtitle file) with this function, it will give true. – Silvio Guedes May 04 '21 at 03:37
  • "FACT: No! It's definitely legal to use try/catch, especially in a case like this." So you mean when using a crappy language like javascript, one must perpetuate the hacking with even more crappy hacking! – Midiman Jun 02 '23 at 13:30
26

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.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 7
    This is wrong, there are many other json-compatible mediatypes. Furthermore `overrideMimeType` can override the content-type header. – Knu Jun 18 '17 at 22:39
  • 2
    Server can pass whatever header type it wants though. Client can't assume what they're getting back is actual JSON. Headers could also be spoofed – user2402616 Mar 08 '22 at 19:18
  • My understanding of `Make sure the server is responding with the correct content-type and test that.` is that you expect the response in the body complies to the value of the [content-type header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type). But this might not be the case. And the question of OP wants to test if the body matches the content-type. Could you clarify what you mean by `test that`? – surfmuggle Mar 04 '23 at 10:09
17

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')) {}
rémy
  • 1,026
  • 13
  • 18
9

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
efkan
  • 12,991
  • 6
  • 73
  • 106
  • 1
    I've created a fiddle for this answer at https://jsfiddle.net/fatmonk/gpn4eyav/ which includes the option of adding your own user test data as well. This looks like the basis of a good library function to me, but I'd like to understand more about why Test 1 is not a valid JSON array. – Fat Monk Jan 04 '17 at 10:25
  • Because an array must be specified by using `[` and `]`. For instance, `[1, 2, 3]` is a number array. `["a", "b", "c"]` is a string array. And `[{"a":1}, {"b":2}]` is a JSON array. Your jsfiddle work seems really useful! – efkan Jan 04 '17 at 13:07
  • As simple as that?! So Test 1 is a JSON object and Test 2 is a JSON array consisting of a single JSON object element. Have I understood that correctly? – Fat Monk Jan 04 '17 at 13:11
  • The question flagged as a possible duplicate of this (http://stackoverflow.com/questions/3710204/how-to-check-if-a-string-is-a-valid-json-string-in-javascript-without-using-try) asks about achieving this without using try/catch so I've forked my fiddle to try to achieve that goal as well. The fork is at https://jsfiddle.net/fatmonk/827jsuvr/ and works with all tests above except for Test 3 which errors at the `JSON.parse`. Can anyone advise how to avoid that error without using try? – Fat Monk Jan 04 '17 at 17:04
  • Your `jsfiddle` application throws an error because of Test 3 doesn't have a valid JSON expression. So a `try-catch` must be used to catch that error and to evaluate any error as the expression is not JSON when parsing like Test 3 above: `try { JSON.parse(data3) } catch(e) { isValidJSON = false }` – efkan Jan 04 '17 at 17:22
  • I understand why I'm getting the exception, but I was hoping I could trap the cause of the exception /before/ running the JSON.parse.... However now that I think about it properly that's a circular question! To avoid the exception of need to check for valid JSON /before/ running JSON.parse - BUT checking for valid JSON ifs exactly what we're trying to do with the function. So tthe function I was trying to create would need to call another function that could perform the same task that my function was supposed to achieve - making my function pointless. So I was being a bit stupid! – Fat Monk Jan 05 '17 at 08:20
8
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.

ZER0
  • 24,846
  • 5
  • 51
  • 54
7

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;
}
5

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);
}
Devashish Mamgain
  • 2,077
  • 1
  • 18
  • 39
5

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.

mdm
  • 12,480
  • 5
  • 34
  • 53
5

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',
});
Lucas Batistussi
  • 2,283
  • 3
  • 27
  • 35
4

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

carlin.scott
  • 6,214
  • 3
  • 30
  • 35
  • @DukeDougal care to clarify? Sometimes people start their json with a '[' but that's not terribly common. – carlin.scott Jun 08 '16 at 23:01
  • 1
    You need to parse it to work out of it is valid JSON. If it is invalid JSON then it is not JSON. The question is "how tell tell if a string is JSON or not?". By your approach, this would be JSON {fibble - and it's really not JSON. Consider also cases like the number 1 on its own - that is valid JSON. – Duke Dougal Jun 09 '16 at 02:51
  • 1
    "If it is invalid JSON then it is not JSON". The fact that you have to use the word "valid" shows that you're adding a qualification to the fact that it's more than just json. The question was simply "is it json" and my code example answers that question perfectly without assuming additional requirements. – carlin.scott Jun 09 '16 at 21:43
  • bad idea if you are using some of template systems and you have something like `{ someValue }` will automatically pass the validation. – ncubica Sep 06 '16 at 21:30
  • @ncubica so you're using a template for something other than json, the string only contains a placeholder that uses curly braces, and the template engine fails to replace the placeholder with the real value? Also keep in mind, like I explained to Duke already, the original question doesn't mention validation. They only wanted to know if it looked like json or not. – carlin.scott Sep 06 '16 at 22:43
  • this is pretty much how angular does is, look for isJsonLike in angular.js (you should also account for arrays ie starts with '[') – Anthony Johnston May 24 '17 at 10:50
  • this actually helped me, but I'm in a weird situation. My string will either be valid json or it will not begin and end with `[` and `]` at all. And I'm using google script debugger, which is so stupid it debug breaks on a `catch` statement and there's no way to turn that behavior off. So now I can make a `isJson` function that doesn't need a try/catch, and be on my merry way. Been a coder for 25 years and sometimes the best solution is the most low-tech solution. Thanks! – toddmo Nov 29 '19 at 02:25
3

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;
};
Mehdi Dehghani
  • 10,970
  • 6
  • 59
  • 64
2

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('-----------------')
elbik
  • 1,749
  • 2
  • 16
  • 21
2

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:

  1. More thorough and continually up-to-date as JSON spec changes
  2. 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.

Ron S.
  • 563
  • 5
  • 13
2

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;
}
Bablu Ahmed
  • 4,412
  • 5
  • 49
  • 64
2

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 :)

Marvin
  • 647
  • 7
  • 15
2

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);
}
James Sumners
  • 14,485
  • 10
  • 59
  • 77
0

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;
  }
}
Rishabh Anand
  • 763
  • 7
  • 8
0

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;

}
sibi mahesh
  • 51
  • 1
  • 1
-1

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
Stepan Novikov
  • 1,402
  • 12
  • 22
ycjcl868
  • 432
  • 3
  • 7
  • 18
-1

function isJsonString(value) {
  try {
    return typeof JSON.parse(value) === 'object';
  } catch (e) {
    return false;
  }
}
console.log('null:',isJsonString('null'))
console.log('[]:',isJsonString('[]'))
console.log('"":',isJsonString(''))
console.log('100:',isJsonString('100'))
console.log('id:',isJsonString('id'))
console.log('{}:',isJsonString('{}'))
console.log('{"a":56}:',isJsonString('{"a":56}'))

This handled most of the required cases for me but not all of them!

rebinnaf
  • 276
  • 2
  • 9