Cómo resolver TypeError: no se puede convertir indefinido o nulo en objeto


90

Escribí un par de funciones que replican efectivamente JSON.stringify (), convirtiendo un rango de valores en versiones en cadena. Cuando transfiero mi código a JSBin y lo ejecuto en algunos valores de muestra, funciona bien. Pero recibo este error en un corredor de especificaciones diseñado para probar esto.

Mi código:

  // 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) + "";
    }
};

El mensaje de error que recibo del probador es:

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)

Parece fallar con: stringifyJSON (null) por ejemplo


1
proporcione la entrada para la que está obteniendo el error, ya que funciona para stringifyJSON ({a: 'b', c: 'd'})
vinayakj

1
Aparte del error, stringifyJSON([1,2,3])devoluciones 1,2,3y stringifyJSON({foo: 'bar'})devoluciones {foo: "bar"}, las cuales no son JSON válidas.
Felix Kling

4
Mi conjetura sería esta línea if (obj === 'null') { return null;} // null unchanged, que no pasará cuando se proporcione null, solo si se le da la cadena "null". Entonces, si pasa el nullvalor real a su secuencia de comandos, se analizará en la parte Objeto del código. Y Object.keys(null)lanza lo TypeErrormencionado. Para solucionarlo, use if(obj === null) {return null}- sin las preguntas alrededor null.
veproza

1
Otro problema: su código no maneja la posibilidad de "caracteres incrustados en cadenas.
Puntiagudo

@Pointy - sí, tendré que agregar algo de lógica para eso ... gracias
zahabba

Respuestas:


131

Respuesta genérica

Este error se produce cuando llamas a una función que espera un Objeto como argumento, pero pasa undefined o null en su lugar, como por ejemplo

Object.keys(null)
Object.assign(window.UndefinedVariable, {})

Como suele ser por error, la solución es verificar su código y corregir la condición nula / indefinida para que la función obtenga un objeto adecuado o no se llame en absoluto.

Object.keys({'key': 'value'})
if (window.UndefinedVariable) {
    Object.assign(window.UndefinedVariable, {})
}

Respuesta específica al código en cuestión

La línea if (obj === 'null') { return null;} // null unchanged no se evaluará cuando se proporcione null, solo si se proporciona la cadena "null". Entonces, si pasa el nullvalor real a su secuencia de comandos, se analizará en la parte Objeto del código. Y Object.keys(null)lanza lo TypeErrormencionado. Para solucionarlo, use if(obj === null) {return null}- sin los qoutes alrededor de null.


8
Resaltar: "Y Object.keys(null)lanza lo TypeErrormencionado".
falsarella

1
Para agregar otro ejemplo común donde esto sucede: delete obj.propertydondeobj===null
Gio

4

Asegúrese de que el objeto de destino no esté vacío ( nullo undefined).

Puede inicializar el objeto de destino con un objeto vacío como se muestra a continuación:

var destinationObj = {};

Object.assign(destinationObj, sourceObj);

2

Esto es muy útil para evitar errores al acceder a propiedades de objetos nulos o indefinidos.

nulo a objeto indefinido

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

indefinido a objeto vacío

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

nulo a objeto vacío

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

0

Resolví el mismo problema en un proyecto React Native. Lo resolví usando esto.

let data = snapshot.val();
if(data){
  let items = Object.values(data);
}
else{
  //return null
}

0

En mi caso, agregué la extensión Lucid a Chrome y no noté el problema en ese momento. Después de aproximadamente un día de trabajar en el problema y darle la vuelta al programa, en una publicación alguien había mencionado a Lucid. Recordé lo que había hecho, eliminé la extensión de Chrome y volví a ejecutar el programa. El problema desapareció. Estoy trabajando con React. Pensé que esto podría ayudar.


0

Reemplazar

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

con

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

0

Si está usando Laravel , mi problema estaba en el nombre de mi ruta. En lugar:

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

Escribí:

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

y cuando arreglé el nombre del controlador, ¡el código funcionó!


0

En mi caso tenía un par de paréntesis extra ()

En vez de

export default connect(
  someVariable
)(otherVariable)()

Tenia que ser

export default connect(
  someVariable
)(otherVariable)

-2

Tengo el mismo problema con un elemento en un formulario web. Entonces, lo que hice para solucionarlo fue validar. si (Objeto === 'nulo') hacer algo

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.