I’ve written a couple of functions that effectively replicate JSON.stringify(), converting a range of values into stringified versions. When I port my code over to JSBin and run it on some sample values, it functions just fine. But I’m getting this error in a spec runner designed to test this.
My code:
// five lines of comments var stringify = function(obj) { if (typeof obj === 'function') { return undefined;} // return undefined for function if (typeof obj === 'undefined') { return undefined;} // return undefined for undefined if (typeof obj === 'number') { return obj;} // number unchanged if (obj === 'null') { return null;} // null unchanged if (typeof obj === 'boolean') { return obj;} // boolean unchanged if (typeof obj === 'string') { return '"' + obj + '"';} // string gets escaped end-quotes if (Array.isArray(obj)) { return obj.map(function (e) { // uses map() to create new array with stringified elements return stringify(e); }); } else { var keys = Object.keys(obj); // convert object's keys into an array var container = keys.map(function (k) { // uses map() to create an array of key:(stringified)value pairs return k + ': ' + stringify(obj[k]); }); return '{' + container.join(', ') + '}'; // returns assembled object with curly brackets } }; var stringifyJSON = function(obj) { if (typeof stringify(obj) != 'undefined') { return "" + stringify(obj) + ""; } };
The error message I’m getting from the tester is:
TypeError: Cannot convert undefined or null to object at Function.keys (native) at stringify (stringifyJSON.js:18:22) at stringifyJSON (stringifyJSON.js:27:13) at stringifyJSONSpec.js:7:20 at Array.forEach (native) at Context.<anonymous> (stringifyJSONSpec.js:5:26) at Test.Runnable.run (mocha.js:4039:32) at Runner.runTest (mocha.js:4404:10) at mocha.js:4450:12 at next (mocha.js:4330:14)
It seems to fail with: stringifyJSON(null) for example
Advertisement
Answer
Generic answer
This error is caused when you call a function that expects an Object as its argument, but pass undefined or null instead, like for example
Object.keys(null) Object.assign(window.UndefinedVariable, {})
As that is usually by mistake, the solution is to check your code and fix the null/undefined condition so that the function either gets a proper Object, or does not get called at all.
Object.keys({'key': 'value'}) if (window.UndefinedVariable) { Object.assign(window.UndefinedVariable, {}) }
Answer specific to the code in question
The line if (obj === 'null') { return null;} // null unchanged
will not
evaluate when given null
, only if given the string "null"
. So if you pass the actual null
value to your script, it will be parsed in the Object part of the code. And Object.keys(null)
throws the TypeError
mentioned. To fix it, use if(obj === null) {return null}
– without the qoutes around null.