Comment résoudre TypeError: impossible de convertir undefined ou null en objet


90

J'ai écrit quelques fonctions qui répliquent efficacement JSON.stringify (), convertissant une plage de valeurs en versions stringifiées. Lorsque je porte mon code sur JSBin et que je l'exécute sur des exemples de valeurs, cela fonctionne très bien. Mais j'obtiens cette erreur dans un coureur de spécifications conçu pour tester cela.

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

Le message d'erreur que je reçois du testeur est:

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)

Cela semble échouer avec: stringifyJSON (null) par exemple


1
veuillez fournir l'entrée pour laquelle vous obtenez une erreur, car cela fonctionne pour stringifyJSON ({a: 'b', c: 'd'})
vinayakj

1
Mis à part l'erreur, les stringifyJSON([1,2,3])retours 1,2,3et les stringifyJSON({foo: 'bar'})retours {foo: "bar"}, qui ne sont pas tous deux JSON valides.
Felix Kling

4
Ma conjecture serait cette ligne if (obj === 'null') { return null;} // null unchanged, - qui ne passera pas une fois donnée null, seulement si la chaîne est donnée "null". Donc, si vous passez la nullvaleur réelle à votre script, elle sera analysée dans la partie Objet du code. Et Object.keys(null)jette le TypeErrormentionné. Pour résoudre ce problème, utilisez if(obj === null) {return null}- sans les qoutes autour null.
veproza

1
Autre problème: votre code ne gère pas la possibilité d'incorporer des "caractères dans des chaînes.
Pointy

@Pointy - oui, je vais devoir ajouter une logique pour cela ... merci
zahabba

Réponses:


131

Réponse générique

Cette erreur se produit lorsque vous appelez une fonction qui attend un objet comme argument, mais qui transmet à la place undefined ou null , comme par exemple

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

Comme c'est généralement par erreur, la solution est de vérifier votre code et de corriger la condition null / indéfinie afin que la fonction obtienne un objet approprié ou ne soit pas appelée du tout.

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

Réponse spécifique au code en question

La ligne if (obj === 'null') { return null;} // null unchanged ne sera pas évaluée lorsqu'elle est donnée null, seulement si la chaîne est donnée "null". Donc, si vous passez la nullvaleur réelle à votre script, elle sera analysée dans la partie Objet du code. Et Object.keys(null)jette le TypeErrormentionné. Pour résoudre ce problème, utilisez if(obj === null) {return null}- sans les qoutes autour de null.


8
Highlight: "Et Object.keys(null)jette le TypeErrormentionné."
falsarella

1
Pour ajouter un autre exemple courant où cela se produit: delete obj.propertyobj===null
Gio

4

Assurez-vous que l'objet de destination n'est pas vide ( nullou undefined).

Vous pouvez initialiser l'objet de destination avec un objet vide comme ci-dessous:

var destinationObj = {};

Object.assign(destinationObj, sourceObj);

2

Ceci est très utile pour éviter les erreurs lors de l'accès aux propriétés d'objets nuls ou non définis.

null à un objet non défini

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

undefined à un objet vide

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

null à objet vide

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

0

J'ai résolu le même problème dans un projet React Native. Je l'ai résolu en utilisant ceci.

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

0

Dans mon cas, j'ai ajouté l'extension Lucid à ​​Chrome et je n'ai pas remarqué le problème à ce moment-là. Après environ une journée de travail sur le problème et de renversement du programme, dans un message, quelqu'un avait mentionné Lucid. Je me suis souvenu de ce que j'avais fait et j'ai supprimé l'extension de Chrome et j'ai de nouveau exécuté le programme. Le problème avait disparu. Je travaille avec React. J'ai pensé que cela pourrait aider.


0

Remplacer

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

avec

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

0

Si vous utilisez Laravel , mon problème était dans le nom de ma Route. Au lieu:

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

J'ai écrit:

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

et quand j'ai corrigé le nom du contrôleur, le code fonctionnait!


0

Dans mon cas, j'avais une paire de parenthèses supplémentaires ()

Au lieu de

export default connect(
  someVariable
)(otherVariable)()

Ça aurait du être

export default connect(
  someVariable
)(otherVariable)

-2

J'ai le même problème avec un élément dans un formulaire Web. Donc, ce que j'ai fait pour le réparer, c'était valider. if (Object === 'null') faire quelque chose

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.