106

My server side code returns a value which is a JSON object on success and a string 'false' on failure. Now how can I check whether the returned value is a JSON object?

Syscall
  • 16,959
  • 9
  • 22
  • 41
bart
  • 13,952
  • 20
  • 65
  • 93
  • 2
    If it's actually "your" server side code, why not have a status field in the JSON result rather than creating this "sometimes-it's-JSON-and-sometimes-it's-not" situation...? – HostileFork says dont trust SE Nov 28 '10 at 06:53
  • @Hostile For debugging reasons. You never now which kind of failure the server will throw and at that point json is not being used. – bart Nov 28 '10 at 18:21
  • 1
    I still don't see how having an error code (as a named field) in the server response would undermine that. It's good enough for Freebase! http://wiki.freebase.com/wiki/MQL_errors – HostileFork says dont trust SE Nov 30 '10 at 09:44
  • Please change the accepted answer to Serguei Federov's, if you can the currently accepted answer is incorrect. – Serj Sagan Nov 03 '15 at 21:09
  • What's a "json object"? There's JSON strings and JS objects, but there's no such thing as a "JavaScript Object Notation object". – mpen Mar 16 '16 at 19:36
  • @mpen see my answer for details – samvv Dec 05 '17 at 21:26
  • @samvv Your answer doesn't address my question. There's no such thing as a "json object". JSON is a *text* format. – mpen Dec 05 '17 at 21:39
  • @mpen You're right, I'm sorry. I noticed it too late. – samvv Dec 06 '17 at 14:31
  • [There is no such thing as a "JSON Object"](https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation). – str Oct 28 '18 at 14:18

13 Answers13

151

The chosen solution doesn't actually work for me because I get a

     "Unexpected Token <" 

error in Chrome. This is because the error is thrown as soon as the parse comes across and unknown character. However, there is a way around this if you are returning only string values through ajax (which can be fairly useful if you are using PHP or ASPX to process ajax requests and might or might not return JSON depending on conditions)

The solution is quite simple, you can do the following to check if it was a valid JSON return

       var IS_JSON = true;
       try
       {
               var json = $.parseJSON(msg);
       }
       catch(err)
       {
               IS_JSON = false;
       }                

As I have said before, this is the solution for if you are either returning string type stuff from your AJAX request or if you are returning mixed type.

Community
  • 1
  • 1
Serguei Fedorov
  • 6,947
  • 9
  • 55
  • 86
  • The question isn't about non-JSON-strings in any point. The server returns **always** a valid JSON (a string `false` is also valid JSON). The question is only about a single point: how to differentiate if the parsed JSON-string is a boolean `false` or an object – Dr.Molle Feb 06 '15 at 22:55
  • 2
    Performance consideration: Wrapping this in a function, make sure to not parse the json twice (once inside the try catch, and once in the code that calls the function.) – Michiel Cornille Mar 31 '15 at 08:36
  • It's a helpers function [isJSON()](https://stackoverflow.com/a/31508686/2578107) that you can use: ```isJSON(someValue)```. – Chofoteddy Nov 09 '18 at 22:09
111

jQuery.parseJSON() should return an object of type "object", if the string was JSON, so you only have to check the type with typeof

var response=jQuery.parseJSON('response from server');
if(typeof response =='object')
{
  // It is JSON
}
else
{
  if(response ===false)
  {
     // the response was a string "false", parseJSON will convert it to boolean false
  }
  else
  {
    // the response was something else
  }
}
Dr.Molle
  • 113,505
  • 14
  • 184
  • 194
  • 31
    Might also need to use a try / catch for exceptions if it is possible that parseJSON is going to be dealing with something other than JSON values (i.e. HTML) – acorncom Mar 22 '12 at 22:44
  • 2
    Prior to jQuery 1.9, $.parseJSON returned null instead of throwing an error if it was passed an empty string, null, or undefined, even though those are not valid JSON. [jquery site link](http://api.jquery.com/jQuery.parseJSON/) – gloomy.penguin Mar 27 '13 at 20:44
  • 7
    This solution is not the best, because return `"SyntaxError: JSON.parse: unexpected character"` error! , I thinks the best solution is use try/catch that said by `Serguei Fedorov` in here: http://stackoverflow.com/questions/4295386/how-can-i-check-if-a-value-is-a-json-object/12217209#12217209 – Nabi K.A.Z. Dec 24 '13 at 18:58
  • 2
    If you don't want to use jquery, you can use vanilla JS by checking constructor type as described here : http://stackoverflow.com/questions/11182924/how-to-check-if-javascript-object-is-json – Mat Apr 21 '14 at 09:10
  • $.parseJSON expects a well-formed JSON string, and if it doesn't get one, an error is thrown, so this answer won't do it. You need to use a try/catch, as the answer below suggests. (Sure would be sweet if jQuery had an "isJSON()" function...) – hairbo Feb 06 '15 at 21:45
  • @hairbo: The question was about JSON, including a string `"false"`(which is valid JSON too), it wasn't about object-literals, also not about non-well-formed JSON. Read the question before you downvote an answer! – Dr.Molle Feb 06 '15 at 21:59
  • @Dr.Molle okay, fair enough. I'd argue that assuming the returned value is either a well-formed JSON string or "false" is not a strong enough test. The server could bomb for unexpected reasons, and you need your client code to handle that condition, hence the desire for an "isJSON()" function. – hairbo Feb 09 '15 at 15:59
  • 2
    This answer is incorrect, the answer by Serguei Federov should be the accepted answer. – Serj Sagan Nov 03 '15 at 21:08
  • The reason that I'm vote down this answer is becasuse is wrong first parse and then validate if this is a objetc type of. How you can parse nothing if your are returning anything or an empty string or json from your server? This is wrong and this answer is not usefull. – Fernando Torres Jun 11 '16 at 22:16
  • @Fernando Urban: how would you work with the response without parsing it? In any case the response will be a string before it will be parsed – Dr.Molle Jun 12 '16 at 00:36
  • No. If your are working with a set time out in javascript that recieves each minute any answer from the server but this depends like an "echo json_encode($value)" that have an IF ELSE statement and if is any boolean true result this will return a json_encode but if this is false this will return nothing. So, how you can parse nothing if you are no returning anything even you can return something but you still not wanting return something? – Fernando Torres Jun 12 '16 at 15:44
  • I this case, you have to try and catch the JSON, like the answer below – Fernando Torres Jun 12 '16 at 15:45
  • Maybe I repeat myself, but when you read the question once more you will recognize that the response is always **valid JSON** ....no need to try/catch anything – Dr.Molle Jun 12 '16 at 15:51
  • I know this thread is more than a year old, but if it's always a valid JSON, then why even bother to check? – oaskamay Sep 12 '17 at 21:48
  • People really need to quit answering Javascript questions with jQuery without providing a jquery-less alternative. Many JS environments are not compatible with jQuery. – lilHar Jan 21 '19 at 16:30
  • 1
    @liljoshu : maybe you didn't notice that the question has been tagged with `jquery` by the author ? – Dr.Molle Jan 22 '19 at 12:05
21

Solution 3 (fastest way)

/**
 * @param Object
 * @returns boolean
 */
function isJSON (something) {
    if (typeof something != 'string')
        something = JSON.stringify(something);

    try {
        JSON.parse(something);
        return true;
    } catch (e) {
        return false;
    }
}

You can use it:

var myJson = [{"user":"chofoteddy"}, {"user":"bart"}];
isJSON(myJson); // true

The best way to validate that an object is of type JSON or array is as follows:

var a = [],
    o = {};

Solution 1

toString.call(o) === '[object Object]'; // true
toString.call(a) === '[object Array]'; // true

Solution 2

a.constructor.name === 'Array'; // true
o.constructor.name === 'Object'; // true

But, strictly speaking, an array is part of a JSON syntax. Therefore, the following two examples are part of a JSON response:

console.log(response); // {"message": "success"}
console.log(response); // {"user": "bart", "id":3}

And:

console.log(response); // [{"user":"chofoteddy"}, {"user":"bart"}]
console.log(response); // ["chofoteddy", "bart"]

AJAX / JQuery (recommended)

If you use JQuery to bring information via AJAX. I recommend you put in the "dataType" attribute the "json" value, that way if you get a JSON or not, JQuery validate it for you and make it known through their functions "success" and "error". Example:

$.ajax({
    url: 'http://www.something.com',
    data: $('#formId').serialize(),
    method: 'POST',
    dataType: 'json',
    // "sucess" will be executed only if the response status is 200 and get a JSON
    success: function (json) {},
    // "error" will run but receive state 200, but if you miss the JSON syntax
    error: function (xhr) {}
});
Chofoteddy
  • 657
  • 6
  • 18
13

If you have jQuery, use isPlainObject.

if ($.isPlainObject(my_var)) {}
thnee
  • 5,416
  • 3
  • 24
  • 22
  • 5
    If you use isPlainObject on a string it return false, e.g. jQuery.isPlainObject('{}') – Roy Shoa Jan 26 '15 at 09:48
  • More importantly, if it contains a non-JSON-like value as a property, according to the docs this function will still return `true`. – samvv Dec 05 '17 at 19:34
6
var checkJSON = function(m) {

   if (typeof m == 'object') { 
      try{ m = JSON.stringify(m); }
      catch(err) { return false; } }

   if (typeof m == 'string') {
      try{ m = JSON.parse(m); }
      catch (err) { return false; } }

   if (typeof m != 'object') { return false; }
   return true;

};


checkJSON(JSON.parse('{}'));      //true
checkJSON(JSON.parse('{"a":0}')); //true
checkJSON('{}');                  //true
checkJSON('{"a":0}');             //true
checkJSON('x');                   //false
checkJSON('');                    //false
checkJSON();                      //false
luizhp
  • 104
  • 1
  • 4
4

Since it's just false and json object, why don't you check whether it's false, otherwise it must be json.

if(ret == false || ret == "false") {
    // json
}
Andreas Wong
  • 55,398
  • 19
  • 100
  • 120
2

I know this thread has been answered already, but coming here didn't really solve my problems, I found this function somewhere else. maybe someone coming here will find it to be of some use to them;

function getClass(obj) {
  if (typeof obj === "undefined")
    return "undefined";
  if (obj === null)
    return "null";
  return Object.prototype.toString.call(obj)
    .match(/^\[object\s(.*)\]$/)[1];
}
pythonian29033
  • 4,817
  • 5
  • 29
  • 56
1
var data = 'json string ?';
var jdata = null;
try
{
    jdata = $.parseJSON(data);  
}catch(e)
{}

if(jdata)
{
//use jdata
}else
{
//use data
}
0

If you want to test explicitly for valid JSON (as opposed to the absence of the returned value false), then you can use a parsing approach as described here.

Community
  • 1
  • 1
Ken Redler
  • 22,899
  • 7
  • 55
  • 68
0

I don't really like the accepted answer. First and foremost it requires jQuery, which is not always available or required. Secondly, it does a full stringification of the object which to me is overkill. Here's a simple function that thoroughly detects whether a value is JSON-like, using nothing more than a few parts of the lodash library for genericity.

import * as isNull from 'lodash/isNull'
import * as isPlainObject from 'lodash/isPlainObject'
import * as isNumber from 'lodash/isNumber'
import * as isBoolean from 'lodash/isBoolean'
import * as isString from 'lodash/isString'
import * as isArray from 'lodash/isArray'

function isJSON(val) {
  if (isNull(val)
   || isBoolean(val)
   || isString(val))
    return true;
  if (isNumber(val)) 
     return !isNaN(val) && isFinite(val)
  if (isArray(val))
    return Array.prototype.every.call(val, isJSON)
  if (isPlainObject(val)) {
    for (const key of Object.keys(val)) {
      if (!isJSON(val[key]))
        return false
    }
    return true
  }
  return false
}

I've even taken the time to put it up in npm as a package: https://npmjs.com/package/is-json-object. Use it together with something like Webpack to get it in the browser.

Hope this helps someone!

samvv
  • 1,514
  • 1
  • 16
  • 22
0

I am using this to validate JSON Object

function isJsonObject(obj) {
    try {
        JSON.parse(JSON.stringify(obj));
    } catch (e) {
        return false;
    }
    return true;
}

I am using this to validate JSON String

function isJsonString(str) {
    try {
        JSON.parse(str);
    } catch (e) {
        return false;
    }
    return true;
}
Abhishek Goel
  • 15,517
  • 8
  • 81
  • 62
0

i tried all of the suggested answers, nothing worked for me, so i had to use

jQuery.isEmptyObject()

hoe that helps someone else out with this issue

Jay Rizzi
  • 3,922
  • 5
  • 33
  • 62
-1

You should return json always, but change its status, or in following example the ResponseCode property:

if(callbackResults.ResponseCode!="200"){
    /* Some error, you can add a message too */
} else {
    /* All fine, proceed with code */
};
skobaljic
  • 8,855
  • 1
  • 23
  • 47
kobe
  • 14,757
  • 15
  • 58
  • 87
  • @bart , you can just provide the object in the if condition , that will do the check. – kobe Nov 28 '10 at 04:38