How to check if JavaScript object is JSON

JavascriptJson

Javascript Problem Overview


I have a nested JSON object that I need to loop through, and the value of each key could be a String, JSON array or another JSON object. Depending on the type of object, I need to carry out different operations. Is there any way I can check the type of the object to see if it is a String, JSON object or JSON array?

I tried using typeof and instanceof but both didn't seem to work, as typeof will return an object for both JSON object and array, and instanceof gives an error when I do obj instanceof JSON.

To be more specific, after parsing the JSON into a JS object, is there any way I can check if it is a normal string, or an object with keys and values (from a JSON object), or an array (from a JSON array)?

For example:

JSON

var data = "{'hi':
             {'hello':
               ['hi1','hi2']
             },
            'hey':'words'
           }";

Sample JavaScript

var jsonObj = JSON.parse(data);
var path = ["hi","hello"];

function check(jsonObj, path) {
    var parent = jsonObj;
    for (var i = 0; i < path.length-1; i++) {
        var key = path[i];
        if (parent != undefined) {
            parent = parent[key];
        }
    }
    if (parent != undefined) {
        var endLength = path.length - 1;
        var child = parent[path[endLength]];
        //if child is a string, add some text
        //if child is an object, edit the key/value
        //if child is an array, add a new element
        //if child does not exist, add a new key/value
    }
}

How do I carry out the object checking as shown above?

Javascript Solutions


Solution 1 - Javascript

I'd check the constructor attribute.

e.g.

var stringConstructor = "test".constructor;
var arrayConstructor = [].constructor;
var objectConstructor = ({}).constructor;

function whatIsIt(object) {
    if (object === null) {
        return "null";
	}
    if (object === undefined) {
        return "undefined";
    }
    if (object.constructor === stringConstructor) {
		return "String";
	}
	if (object.constructor === arrayConstructor) {
		return "Array";
	}
	if (object.constructor === objectConstructor) {
		return "Object";
	}
	{
		return "don't know";
	}
}

var testSubjects = ["string", [1,2,3], {foo: "bar"}, 4];

for (var i=0, len = testSubjects.length; i < len; i++) {
	alert(whatIsIt(testSubjects[i]));
}

Edit: Added a null check and an undefined check.

Solution 2 - Javascript

You can use Array.isArray to check for arrays. Then typeof obj == 'string', and typeof obj == 'object'.

var s = 'a string', a = [], o = {}, i = 5;
function getType(p) {
    if (Array.isArray(p)) return 'array';
    else if (typeof p == 'string') return 'string';
    else if (p != null && typeof p == 'object') return 'object';
    else return 'other';
}
console.log("'s' is " + getType(s));
console.log("'a' is " + getType(a));
console.log("'o' is " + getType(o));
console.log("'i' is " + getType(i));

> 's' is string
'a' is array
'o' is object
'i' is other

Solution 3 - Javascript

An JSON object is an object. To check whether a type is an object type, evaluate the constructor property.

function isObject(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Object;
}

The same applies to all other types:

function isArray(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Array;
}

function isBoolean(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Boolean;
}

function isFunction(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Function;
}

function isNumber(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == Number;
}

function isString(obj)
{
    return obj !== undefined && obj !== null && obj.constructor == String;
}

function isInstanced(obj)
{
    if(obj === undefined || obj === null) { return false; }
    
    if(isArray(obj)) { return false; }
    if(isBoolean(obj)) { return false; }
    if(isFunction(obj)) { return false; }
    if(isNumber(obj)) { return false; }
    if(isObject(obj)) { return false; }
    if(isString(obj)) { return false; }
    
    return true;
}

Solution 4 - Javascript

If you are trying to check the type of an object after you parse a JSON string, I suggest checking the constructor attribute:

obj.constructor == Array || obj.constructor == String || obj.constructor == Object

This will be a much faster check than typeof or instanceof.

If a JSON library does not return objects constructed with these functions, I would be very suspiciouse of it.

Solution 5 - Javascript

you can also try to parse the data and then check if you got object:

try {
    var testIfJson = JSON.parse(data);
    if (typeof testIfJson == "object"){
        //Json
    } else {
        //Not Json
    }
}
catch {
    return false;
}

Solution 6 - Javascript

The answer by @PeterWilkinson didn't work for me because a constructor for a "typed" object is customized to the name of that object. I had to work with typeof

function isJson(obj) {
    var t = typeof obj;
    return ['boolean', 'number', 'string', 'symbol', 'function'].indexOf(t) == -1;
}

Solution 7 - Javascript

You could make your own constructor for JSON parsing:

var JSONObj = function(obj) { $.extend(this, JSON.parse(obj)); }
var test = new JSONObj('{"a": "apple"}');
//{a: "apple"}

Then check instanceof to see if it needed parsing originally

test instanceof JSONObj

Solution 8 - Javascript

I wrote an npm module to solve this problem. It's available here:

object-types: a module for finding what literal types underly objects

Install

  npm install --save object-types


Usage

const objectTypes = require('object-types');

objectTypes({});
//=> 'object'

objectTypes([]);
//=> 'array'

objectTypes(new Object(true));
//=> 'boolean'

Take a look, it should solve your exact problem. Let me know if you have any questions! https://github.com/dawsonbotsford/object-types

Solution 9 - Javascript

Why not check Number - a bit shorter and works in IE/Chrome/FF/node.js

function whatIsIt(object) {
    if (object === null) {
        return "null";
    }
    else if (object === undefined) {
        return "undefined";
    }
    if (object.constructor.name) {
            return object.constructor.name;
    }
    else { // last chance 4 IE: "\nfunction Number() {\n    [native code]\n}\n" / node.js: "function String() { [native code] }"
        var name = object.constructor.toString().split(' ');
        if (name && name.length > 1) {
            name = name[1];
            return name.substr(0, name.indexOf('('));
        }
        else { // unreachable now(?)
            return "don't know";
        }
    }
}

var testSubjects = ["string", [1,2,3], {foo: "bar"}, 4];
// Test all options
console.log(whatIsIt(null));
console.log(whatIsIt());
for (var i=0, len = testSubjects.length; i < len; i++) {
    console.log(whatIsIt(testSubjects[i]));
}

Solution 10 - Javascript

I combine the typeof operator with a check of the constructor attribute (by Peter):

var typeOf = function(object) {
    var firstShot = typeof object;
    if (firstShot !== 'object') {
        return firstShot;
    } 
    else if (object.constructor === [].constructor) {
        return 'array';
    }
    else if (object.constructor === {}.constructor) {
        return 'object';
    }
    else if (object === null) {
        return 'null';
    }
    else {
        return 'don\'t know';
    } 
}

// Test
var testSubjects = [true, false, 1, 2.3, 'string', [4,5,6], {foo: 'bar'}, null, undefined];

console.log(['typeOf()', 'input parameter'].join('\t'))
console.log(new Array(28).join('-'));
testSubjects.map(function(testSubject){
    console.log([typeOf(testSubject), JSON.stringify(testSubject)].join('\t\t'));
});

Result:

typeOf()	input parameter
---------------------------
boolean		true
boolean		false
number		1
number		2.3
string		"string"
array		[4,5,6]
object		{"foo":"bar"}
null		null
undefined		

Solution 11 - Javascript

I know this is a very old question with good answers. However, it seems that it's still possible to add my 2¢ to it.

Assuming that you're trying to test not a JSON object itself but a String that is formatted as a JSON (which seems to be the case in your var data), you could use the following function that returns a boolean (is or is not a 'JSON'):

function isJsonString( jsonString ) {

  // This function below ('printError') can be used to print details about the error, if any.
  // Please, refer to the original article (see the end of this post)
  // for more details. I suppressed details to keep the code clean.
  //
  let printError = function(error, explicit) {
  console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
  }


  try {
      JSON.parse( jsonString );
      return true; // It's a valid JSON format
  } catch (e) {
      return false; // It's not a valid JSON format
  }

}

Here are some examples of using the function above:

console.log('\n1 -----------------');
let j = "abc";
console.log( j, isJsonString(j) );

console.log('\n2 -----------------');
j = `{"abc": "def"}`;
console.log( j, isJsonString(j) );

console.log('\n3 -----------------');
j = '{"abc": "def}';
console.log( j, isJsonString(j) );

console.log('\n4 -----------------');
j = '{}';
console.log( j, isJsonString(j) );

console.log('\n5 -----------------');
j = '[{}]';
console.log( j, isJsonString(j) );

console.log('\n6 -----------------');
j = '[{},]';
console.log( j, isJsonString(j) );

console.log('\n7 -----------------');
j = '[{"a":1, "b":   2}, {"c":3}]';
console.log( j, isJsonString(j) );

When you run the code above, you will get the following results:

1 -----------------
abc false

2 -----------------
{"abc": "def"} true

3 -----------------
{"abc": "def} false

4 -----------------
{} true

5 -----------------
[{}] true

6 -----------------
[{},] false

7 -----------------
[{"a":1, "b":   2}, {"c":3}] true

Please, try the snippet below and let us know if this works for you. :)

IMPORTANT: the function presented in this post was adapted from https://airbrake.io/blog/javascript-error-handling/syntaxerror-json-parse-bad-parsing where you can find more and interesting details about the JSON.parse() function.

function isJsonString( jsonString ) {

  let printError = function(error, explicit) {
  console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
  }


  try {
      JSON.parse( jsonString );
      return true; // It's a valid JSON format
  } catch (e) {
      return false; // It's not a valid JSON format
  }

}


console.log('\n1 -----------------');
let j = "abc";
console.log( j, isJsonString(j) );

console.log('\n2 -----------------');
j = `{"abc": "def"}`;
console.log( j, isJsonString(j) );

console.log('\n3 -----------------');
j = '{"abc": "def}';
console.log( j, isJsonString(j) );

console.log('\n4 -----------------');
j = '{}';
console.log( j, isJsonString(j) );

console.log('\n5 -----------------');
j = '[{}]';
console.log( j, isJsonString(j) );

console.log('\n6 -----------------');
j = '[{},]';
console.log( j, isJsonString(j) );

console.log('\n7 -----------------');
j = '[{"a":1, "b":   2}, {"c":3}]';
console.log( j, isJsonString(j) );

Solution 12 - Javascript

Try this

if ( typeof is_json != "function" )
function is_json( _obj )
{
    var _has_keys = 0 ;
    for( var _pr in _obj )
    {
        if ( _obj.hasOwnProperty( _pr ) && !( /^\d+$/.test( _pr ) ) )
        {
           _has_keys = 1 ;
           break ;
        }
    }

    return ( _has_keys && _obj.constructor == Object && _obj.constructor != Array ) ? 1 : 0 ;
}

It works for the example below

var _a = { "name" : "me",
       "surname" : "I",
       "nickname" : {
                      "first" : "wow",
                      "second" : "super",
                      "morelevel" : {
                                      "3level1" : 1,
                                      "3level2" : 2,
                                      "3level3" : 3
                                    }
                    }
     } ;

var _b = [ "name", "surname", "nickname" ] ;
var _c = "abcdefg" ;

console.log( is_json( _a ) );
console.log( is_json( _b ) );
console.log( is_json( _c ) );

Solution 13 - Javascript

Based on @Martin Wantke answer, but with some recommended improvements/adjusts...

// NOTE: Check JavaScript type. By Questor
function getJSType(valToChk) {

    function isUndefined(valToChk) { return valToChk === undefined; }
    function isNull(valToChk) { return valToChk === null; }
    function isArray(valToChk) { return valToChk.constructor == Array; }
    function isBoolean(valToChk) { return valToChk.constructor == Boolean; }
    function isFunction(valToChk) { return valToChk.constructor == Function; }
    function isNumber(valToChk) { return valToChk.constructor == Number; }
    function isString(valToChk) { return valToChk.constructor == String; }
    function isObject(valToChk) { return valToChk.constructor == Object; }

    if(isUndefined(valToChk)) { return "undefined"; }
    if(isNull(valToChk)) { return "null"; }
    if(isArray(valToChk)) { return "array"; }
    if(isBoolean(valToChk)) { return "boolean"; }
    if(isFunction(valToChk)) { return "function"; }
    if(isNumber(valToChk)) { return "number"; }
    if(isString(valToChk)) { return "string"; }
    if(isObject(valToChk)) { return "object"; }

}

NOTE: I found this approach very didactic, so I submitted this answer.

Solution 14 - Javascript

Try, Catch block will help you to solve this

Make a function

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

Example:

console.log(IsJson('abc')) // false
console.log(IsJson('[{"type":"email","detail":"[email protected]"}]')) // true

Solution 15 - Javascript

Peter's answer with an additional check! Of course, not 100% guaranteed!

var isJson = false;
outPutValue = ""
var objectConstructor = {}.constructor;
if(jsonToCheck.constructor === objectConstructor){
	outPutValue = JSON.stringify(jsonToCheck);
	try{
			JSON.parse(outPutValue);
			isJson = true;
	}catch(err){
			isJson = false;
	}
}

if(isJson){
	alert("Is json |" + JSON.stringify(jsonToCheck) + "|");
}else{
	alert("Is other!");
}

Solution 16 - Javascript

I have a pretty lazy answer to this, which will not throw an error if you try to parse a string/other values.

const checkForJson = (value) => {
    if (typeof value !== "string") return false;

    return value[0] === "{" && value[value.length - 1] === "}";
}

You can use this to check the value of your keys while you make some recursive func; sorry if this doesn't answer the question completely

Ofc this isn't the most elegant solution and will fail when a string actually starts with "{" and ends with "}" although those use cases would be rare, and if you really wanted, you can check for a presence of quotes or other nonsense... anyway, use at your own discretion.

TLDR: it's not bulletproof, but it's simple and works for the vast majority of use cases.

Solution 17 - Javascript

lodash is also the best bet to check these things.

function Foo() {
  this.a = 1;
}
 
_.isPlainObject(new Foo);
// => false
 
_.isPlainObject([1, 2, 3]);
// => false
 
_.isPlainObject({ 'x': 0, 'y': 0 });
// => true
 
_.isPlainObject(Object.create(null));
// => true

https://www.npmjs.com/package/lodash
https://lodash.com/docs/#isPlainObject

Solution 18 - Javascript

Quickly check for a JSON structure using lodash-contrib:

const _ = require('lodash-contrib');

_.isJSON('{"car": "ferarri"}'); //true for stringified
_.isJSON({car: "ferarri"}); //true  

Usage guide: this blog entry

Solution 19 - Javascript

try this dirty way

 ('' + obj).includes('{')

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWei HaoView Question on Stackoverflow
Solution 1 - JavascriptProgramming GuyView Answer on Stackoverflow
Solution 2 - JavascriptMcGarnagleView Answer on Stackoverflow
Solution 3 - JavascriptMartin WantkeView Answer on Stackoverflow
Solution 4 - JavascriptJoshRagemView Answer on Stackoverflow
Solution 5 - JavascriptarielhadView Answer on Stackoverflow
Solution 6 - JavascriptDmitry EfimenkoView Answer on Stackoverflow
Solution 7 - Javascriptmatt3141View Answer on Stackoverflow
Solution 8 - JavascriptDawson BView Answer on Stackoverflow
Solution 9 - JavascriptTomView Answer on Stackoverflow
Solution 10 - JavascriptMartin SkorupskiView Answer on Stackoverflow
Solution 11 - JavascriptAlmir CamposView Answer on Stackoverflow
Solution 12 - JavascriptSandro RosaView Answer on Stackoverflow
Solution 13 - JavascriptEduardo LucioView Answer on Stackoverflow
Solution 14 - JavascriptMostafizur RahmanView Answer on Stackoverflow
Solution 15 - JavascriptEduardo LucioView Answer on Stackoverflow
Solution 16 - JavascriptChronicLogicView Answer on Stackoverflow
Solution 17 - JavascriptMohamed JakkariyaView Answer on Stackoverflow
Solution 18 - JavascriptGavinBelsonView Answer on Stackoverflow
Solution 19 - JavascriptStan SokolovView Answer on Stackoverflow