How to resolve TypeError: Cannot convert undefined or null to object
Asked Answered
A

16

189

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

Appledorf answered 18/4, 2015 at 18:29 Comment(6)
please provide the input for which you are getting error, as its working for stringifyJSON({a:'b',c:'d'})Bursiform
Aside from the error, stringifyJSON([1,2,3]) returns 1,2,3 and stringifyJSON({foo: 'bar'}) returns {foo: "bar"}, both of which are not valid JSON.Altimetry
My guess would be this line if (obj === 'null') { return null;} // null unchanged, - that won't pass 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.Saenz
Another issue: your code does not handle the possibility of embedded " characters in strings.Lucilla
@Lucilla - yes, i'll need to add some logic for that...thank youAppledorf
@Appledorf : no problem. I reposted that as the answer, so your question won't linger in the unanswered section.Saenz
S
223

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.

Saenz answered 18/4, 2015 at 18:50 Comment(2)
Highlight: "And Object.keys(null) throws the TypeError mentioned."Dibranchiate
To add another common example where this happens: delete obj.property where obj===nullMaccabean
W
36

Make sure that object is not empty (null or undefined ).

Error:

let obj

Object.keys(obj)

Solution:

Object.keys(obj || {})
Wanda answered 6/7, 2022 at 11:2 Comment(3)
This is the easiest solution, it worked for me : Object.keys(obj || {})Spoken
This is the best solution, this happens mostly if you are programmatically deciding the value of the object obj and by chance your logic for determining its value returns a falsy value (null or undefined) so telling it to use a truthy value or an object with no property is the best answer.Houk
🤗 Smiling Face with Open Hands || {}Entelechy
P
8

Make sure that destination object is not empty ( null or undefined ).

You can initialize destination object with empty object like below:

var destinationObj = {};

Object.assign(destinationObj, sourceObj);
Pantile answered 19/8, 2019 at 9:21 Comment(0)
P
5

This is very useful to avoid errors when accessing properties of null or undefined objects.

null to undefined object

const obj = null;
const newObj = obj || undefined;
// newObj = undefined

undefined to empty object

const obj; 
const newObj = obj || {};
// newObj = {}     
// newObj.prop = undefined, but no error here

null to empty object

const obj = null;
const newObj = obj || {};
// newObj = {}  
// newObj.prop = undefined, but no error here
Prognostication answered 11/8, 2020 at 13:24 Comment(0)
Z
5

Adding Object && works before putting the object on to map.

objexts && Object.keys(objexts)?.map((objext, idx) => 
Zadazadack answered 13/12, 2021 at 7:19 Comment(2)
this one work like magic on me... thanks !Saluki
This works but is not technically the most efficient solution. Karthikeyan.a solution is more efficient.Houk
B
2

Make sure to always call Object properties on an object:

Object.keys(obj || {}) //so you avoid calling it on null/undefined

It resolved my error!

Barnaba answered 6/12, 2023 at 1:5 Comment(1)
Repeats this answer.Seise
V
1

In my case, I added Lucid extension to Chrome and didn't notice the problem at that moment. After about a day of working on the problem and turning the program upside down, in a post someone had mentioned Lucid. I remembered what I had done and removed the extension from Chrome and ran the program again. The problem was gone. I am working with React. I thought this might help.

Valerivaleria answered 4/4, 2020 at 10:36 Comment(0)
B
0

I solved the same problem in a React Native project. I solved it using this.

let data = snapshot.val();
if(data){
  let items = Object.values(data);
}
else{
  //return null
}
Berdichev answered 31/12, 2019 at 11:44 Comment(0)
R
0

Replace

if (typeof obj === 'undefined') { return undefined;} // return undefined for undefined
if (obj === 'null') { return null;} // null unchanged

with

if (obj === undefined) { return undefined;} // return undefined for undefined 
if (obj === null) { return null;} // null unchanged
Reinsure answered 31/12, 2019 at 19:9 Comment(0)
T
0

If you're using Laravel, my problem was in the name of my Route. Instead:

Route::put('/reason/update', 'REASONController@update');

I wrote:

Route::put('/reason/update', 'RESONController@update');

and when I fixed the controller name, the code worked!

Tubulure answered 8/10, 2020 at 3:58 Comment(0)
S
0

In my case I had an extra pair of parenthesis ()

Instead of

export default connect(
  someVariable
)(otherVariable)()

It had to be

export default connect(
  someVariable
)(otherVariable)
Shaunta answered 21/10, 2020 at 11:38 Comment(0)
W
0

Below snippet is sufficient to understand how I encountered the same issue but in a different scenario and how I solved it using the guidance in the accepted answer. In my case I was trying to log the keys of object present in the 0th index of the 'defaultViewData' array using Object.keys() method.

defaultViewData = [{"name": "DEFAULT_VIEW_PLP","value": {"MSH25": "LIST"}}] 

console.log('DEFAULT_VIEW', Object.keys(this.props.defaultViewData[0]));

The console.log was not getting printed and I was getting the same error as posted in this question. To prevent that error I added below condition

    if(this.props.defaultViewData[0]) {
  console.log('DEFAULT_VIEW', Object.keys(this.props.defaultViewData[0]));
}

Adding this check ensured that I didn't get this error. I hope this helps for someone.

Note: This is React.js code. (although to understand the problem it doesn't matter).

Whelp answered 15/12, 2020 at 4:57 Comment(0)
O
0
reactTraverser.js:6 Uncaught TypeError: Cannot convert undefined or null to object at Function.keys (<anonymous>) at reactTraverser.js:6

If you are getting this error on typeScript Try using it without Live Server this error will not be displayed

Outclass answered 4/1, 2022 at 7:46 Comment(0)
H
0

My API requests got expired so it was passing a null value that was giving this error.

Might as well check your API limits.enter image description here

Huppah answered 30/5, 2023 at 6:42 Comment(0)
P
0

Object.keys(obj ?? {})

It worked for me

Philpott answered 2/1 at 7:30 Comment(0)
T
-1

I have the same problem with a element in a webform. So what I did to fix it was validate. if(Object === 'null') do something

Thay answered 5/7, 2019 at 21:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.