Ways to verify whether a JavaScript object qualifies as JSON

I am facing a challenge with a nested JSON object that requires me to iterate through its keys. The tricky part is that each key's value could be a String, a JSON array, or another JSON object. In order to perform different operations based on the type of object, I need to determine if it is a String, a JSON object, or a JSON array.

Although I attempted using typeof and instanceof, neither method proved successful. typeof incorrectly identifies both JSON objects and arrays as 'object', while instanceof throws an error when I try to use it with obj instanceof JSON.

After parsing the JSON into a JavaScript object, I am seeking a way to ascertain whether it is a regular string, an object with keys and values (from a JSON object), or an array (from a JSON array).

For instance:

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 can I effectively conduct the object checking process showcased above?

Answer №1

One way to determine the type of an object is by checking its constructor attribute.

For example:

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

function findType(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 "unknown";
    }
}

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

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

Edit: Included a check for null and undefined values.

Answer №2

By utilizing the Array.isArray function, you can easily determine if a variable is an array. Then, you can use conditions such as typeof obj == 'string', and typeof obj == 'object'.

let str = 'a string', arr = [], obj = {}, num = 5;
function checkType(param) {
    if (Array.isArray(param)) return 'array';
    else if (typeof param == 'string') return 'string';
    else if (param != null && typeof param == 'object') return 'object';
    else return 'other';
}
console.log("'str' is " + checkType(str));
console.log("'arr' is " + checkType(arr));
console.log("'obj' is " + checkType(obj));
console.log("'num' is " + checkType(num));

'str' is string
'arr' is array
'obj' is object
'num' is other

Answer №3

A JSON object represents an object. To verify if a type is of object type, you can check the constructor property.

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

The same principle applies to other types as well:

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

Answer №4

One approach could be to attempt data parsing and verify its type:

try {
    var parsedData = JSON.parse(data);
    if (typeof parsedData === "object") {
        // Data is in JSON format
    } else {
        // Data is not in JSON format
    }
} catch {
    return false;
}

Answer №5

When verifying the type of an entity following the parsing of a JSON string, it is advisable to inspect the constructor property:

entity.constructor == Array || entity.constructor == String || entity.constructor == Object

This method is more efficient compared to using typeof or instanceof.

If a JSON toolkit fails to generate objects created with these constructors, it should raise concerns.

Answer №6

After trying the solution provided by @PeterWilkinson, I realized it didn't work for my specific case. This is because a constructor for a "typed" object is tailored to the name of that object. To resolve this, I had to utilize typeof

function checkIfJson(object) {
    var type = typeof object;
    return ['boolean', 'number', 'string', 'symbol', 'function'].indexOf(type) == -1;
}

Answer №7

One approach is to create a custom constructor for JSON parsing:

var CustomJSON = function(data) { $.extend(this, JSON.parse(data)); }
var instance = new CustomJSON('{"fruit": "banana"}');
//{fruit: "banana"}

You can then use instanceof to determine if the data needed parsing originally:

instance instanceof CustomJSON

Answer №8

If you're struggling with identifying literal types in objects, I've created an npm module specifically for that purpose. You can find it here:

object-types: a tool designed to uncover the underlying literal types of objects

Installation

  npm install --save object-types


How to Use

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

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

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

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

Feel free to give it a try and see if it fits your needs perfectly. Don't hesitate to reach out if you have any questions! Here's the link: https://github.com/dawsonbotsford/object-types

Answer №9

If you're facing an issue, using a Try and Catch block can be the solution

Create a custom function

function CheckIfJson(data) {
    try {
        JSON.parse(data);
    } catch (error) {
        return false;
    }
    return true;
}

For example:

console.log(CheckIfJson('abc')) // false
console.log(CheckIfJson('[{"type":"email","detail":"<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0c666364624c69746d617c6069226f6361">[email protected]</a>"}]')) // true

Answer №10

Have you tried the Number Checker - it's concise and compatible with IE/Chrome/FF/node.js?

function whatIsIt(obj) {
    if (obj === null) {
        return "null";
    }
    else if (obj === undefined) {
        return "undefined";
    }
    if (obj.constructor.name) {
            return obj.constructor.name;
    }
    else { // last resort for IE: "\nfunction Number() {\n    [native code]\n}\n" / node.js: "function String() { [native code] }"
        var name = obj.constructor.toString().split(' ');
        if (name && name.length > 1) {
            name = name[1];
            return name.substr(0, name.indexOf('('));
        }
        else { // should not be reached(?)
            return "unknown";
        }
    }
}

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

Answer №11

To determine the type of an object, I use a combination of the typeof operator and checking the constructor attribute (inspired by Peter):

var findType = function(item) {
    var initialType = typeof item;
    if (initialType !== 'object') {
        return initialType;
    } 
    else if (item.constructor === [].constructor) {
        return 'array';
    }
    else if (item.constructor === {}.constructor) {
        return 'object';
    }
    else if (item === null) {
        return 'null';
    }
    else {
        return 'unknown';
    } 
}

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

console.log(['findType()', 'input'].join('\t'))
console.log(new Array(28).join('-'));
objectsToTest.map(function(obj){
    console.log([findType(obj), JSON.stringify(obj)].join('\t\t'));
});

Output:

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

Answer №12

Although this question has been around for a while and already has great answers, I believe I can still offer my two cents on the matter.

If you're looking to test not an actual JSON object but rather a String that is formatted as JSON (as seen in your var data), you can utilize the following function that will return a boolean value indicating whether it is 'JSON' or not:

function isJsonString( jsonString ) {

  // The function below ('printError') is used to show error details if any occur.
  // For more in-depth information, refer to the original article linked at the end of this post.
  //
  let printError = function(error, explicit) {
  console.log(`[${explicit ? 'EXPLICIT' : 'INEXPLICIT'}] ${error.name}: ${error.message}`);
  }


  try {
      JSON.parse( jsonString );
      return true; // Valid JSON format
  } catch (e) {
      return false; // Not a valid JSON format
  }

}

Here are some examples demonstrating the usage of the above function:

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

Executing the code snippets above will provide 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

Feel free to test out the snippet below and share with us whether it meets your needs. :)

IMPORTANT: The function described here was adapted from , where you can explore more interesting details about the JSON.parse() functionality.

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; // 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) );

Answer №13

Give this a try

if ( typeof check_json != "function" )
function check_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 ;
}

This code snippet is designed to handle the following scenario:

var _x = { "first_name" : "John",
       "last_name" : "Doe",
       "age_group" : {
                      "adult" : true,
                      "child" : false,
                      "senior" : false
                    }
     } ;

var _y = [ "city", "state", "country" ] ;
var _z = "123456" ;

console.log( check_json( _x ) );
console.log( check_json( _y ) );
console.log( check_json( _z ) );

Answer №14

After reviewing @Martin Wantke's response, I have made some recommended enhancements and adjustments...

// NOTE: Validate JavaScript data types. By Questor
function checkJSType(valueToCheck) {

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

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

}

NOTE: I found this method very instructive, which is why I contributed this answer.

Answer №15

Peter's response which includes an additional verification step! Note that this method is not foolproof.

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

if (isJson) {
    alert("This is a valid JSON: |" + JSON.stringify(jsonToCheck) + "|");
} else {
    alert("Not a JSON!");
}

Answer №16

My approach to this problem might seem a bit lazy, but it's designed not to cause any errors when attempting to parse different types of values.

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

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

This function can be used to validate keys recursively, although I acknowledge that it may not fully answer the question at hand.

Admittedly, this solution is not the most sophisticated and may fail in certain edge cases where a string begins with "{" and ends with "}". However, these scenarios are rare, and additional checks for quotes or other anomalies could be implemented if necessary. Ultimately, use this function cautiously.

TLDR: While not foolproof, this simple method should suffice for the majority of use cases.

Answer №17

lodash is the go-to choice for verifying these types of situations.

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

Explore lodash on npm
Learn more about lodash's isPlainObject method

Answer №18

Need to quickly verify a JSON structure? Utilize lodash-contrib:

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

_.isJSON('{"car": "ferarri"}'); //evaluates to true for stringified data
_.isJSON({car: "ferarri"}); //also returns true  

For more information, check out this usage guide: here

Answer №19

Give this unconventional method a shot

 ('' + object).includes('{')

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

leveraging UI-Router for navigating based on app state and data

Is there a way to dynamically adjust Angular's ui-routing based on certain data conditions? For instance, let's say we need to create a subscription process where the user is informed of whether their subscription was successful or not. As the f ...

Creating a JavaScript anchor through a backend bean function

Is it crazy to want to create an anchor that can be called from a backing bean method using JavaScript? I need to do this for specific reasons, utilizing a commandButton with ajax set to false. I'm attempting the following approach: RequestContext.g ...

Using JavaScript in Selenium, you can check a checkbox and verify whether it is checked

How can I select a checkbox and determine if it is checked using JavaScript, Selenium, and Node.js? I have attempted to use the .click method on the element and also tried native JavaScript code, but unfortunately it has not worked for me. driver.findElem ...

How to use Javascript to pause an HTML5 video when closed

I am new to coding and currently working on a project in Adobe Edge Animate. I have managed to create a return button that allows users to close out of a video and go back to the main menu. However, I am facing an issue where the video audio continues to p ...

The rule 'react-hooks/exhaustive-deps' does not have a defined definition

I received an eslint error message after inserting // eslint-disable-next-line react-hooks/exhaustive-deps into my code. 8:14 error Rule 'react-hooks/exhaustive-deps' definition not found I tried to resolve this issue by referring to this p ...

Transforming a string into JSON with proper sanitization

When web scraping, the website returns a string like this on get request: jQuery18305426675335038453_1429531451051({"d":[{"__metadata":"cool"}]}) The complete code snippet is provided below: var baseUrl = "http://SOMEURL.COM?spatialFilter=nearby(52.4795 ...

Creating a radial gradient effect using JavaScript

I've been experimenting with setting a radial gradient as the background of a div using JavaScript. My goal is to have the gradient start in the middle with around 0.8 opacity, gradually fading to 0 towards the edges to create a soft fading effect. I& ...

Adjusting the duration of the carousel in Bootstrap 4.2

Is there a way to alter the transition or fade duration of a carousel in BS4.2 using scripts? According to the BS documentation: Adjusting transition duration To modify the transition duration of .carousel-item, you can utilize the $carousel-transition Sa ...

In Typescript, you can easily group a string into sections that consist of digits like 345-67, along with text containing a

I have a string that looks like this: "[111-11] text here with digits 111, [222-22-22]; 333-33 text here" and I am trying to parse it so that I can extract the code [111-11], [222-22-22], [333-33] along with their respective text descriptions. The challeng ...

Observing and showing profound modifications in Vue

I need to show a distinct message for each category that the user selects <v-select multiple style="position: relative; top: 20px;" color="white" v-if="count == 3 && question" solo placeholder="Please Cho ...

Activate audio and trigger notification

I'm looking to incorporate a small beep sound into my web application before displaying an alert message. Here's what I currently have: if(_none_valid) { $.playSound('/static/wav/beep_error.wav').delay(300); alert('ERROR: ...

JavaScript: Analyzing the occurrence rate of emojis within text

I'm currently working on a project to tally the frequency of emojis within a body of text. For instance: "I adore ...

Javascript tells the time difference between 1 minute and 1 minutes. A timer is set up to notify when the time is

self.calculateMessageTime = function calculateMessageTime(receiveDate){ var dateReceived = Date.parse(receiveDate); var now = new Date(); now = Date.now(); // in seconds var difference = Math.abs(dateReceived - now)/1000; if(differ ...

Send a member as an array to be converted to JSON in PowerShell

Check out this brief PowerShell code snippet: $users = New-Object System.Collections.ArrayList $userAsJson = ' { "name" : "abc", "companies" : ["facebook", "google"] }' $user = $userAsJson | ConvertFrom-Json $null = $users.Add($user) $us ...

What is the best way to retrieve the parameters from the current URL within an Express function on the backend? (details below)

Struggling to articulate my issue here. I'm in the process of creating a straightforward express app that utilizes the omdb API to search for movie titles and display the results. The challenge is that the omdb API returns the results in pages, with 1 ...

A guide to showcasing a series of strings in a react element

My aim is to present an array of strings on distinct lines within my React component by utilizing the following code: <div> {this.props.notifications.join('\n')} </div> Nonetheless, it appears that this a ...

What is the best way to rearrange DOM elements using the output of a shuffle function?

Looking for a solution to shuffle and move around cards in an HTML memory game? Let's analyze the current setup: <ul class="deck"> <li class="card"> <i class="fa fa-diamond"></i> </li> ...

Is there a way to adjust the size of a specific section within an SVG

My SVG image consists of 2 parts: ____________ | | | | p1 | p2 | |____|______| I am looking for a way to save the width of part p1 and only scale the width of part p2 on the horizontal scale. Can someone please suggest where I can find inform ...

Using Phonegap alongside ons-scroller and ons-button

Recently, I have been using Phonegap with the Onsen UI system on iOS devices. I encountered an issue where buttons included within an ons-scroller were not clickable when running on an iPad or iPhone. Here is the code snippet that caused the problem: < ...

React does not require looping to render arrays directly

So, I've been working with an array called lis and storing elements in it. The interesting part is that when I display this array in React, the entire array gets rendered automatically without me having to use any looping mechanism like map(). It&apos ...