Come risolvere TypeError: Impossibile convertire undefined o null in object


92

Ho scritto un paio di funzioni che replicano efficacemente JSON.stringify (), convertendo un intervallo di valori in versioni con stringhe. Quando porto il mio codice su JSBin e lo eseguo su alcuni valori di esempio, funziona perfettamente. Ma ricevo questo errore in un corridore di specifiche progettato per testarlo.

Il mio codice:

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

Il messaggio di errore che ricevo dal tester è:

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)

Sembra fallire con: stringifyJSON (null) per esempio


1
si prega di fornire l'input per il quale si riceve l'errore, poiché funziona per stringifyJSON ({a: 'b', c: 'd'})
vinayakj

1
A parte l'errore, stringifyJSON([1,2,3])ritorni 1,2,3e stringifyJSON({foo: 'bar'})ritorni {foo: "bar"}, entrambi non sono JSON validi.
Felix Kling

4
La mia ipotesi sarebbe questa linea if (obj === 'null') { return null;} // null unchanged, - che non passerà quando data null, solo se data la stringa "null". Quindi, se passi il nullvalore effettivo al tuo script, verrà analizzato nella parte Object del codice. E Object.keys(null)lancia il TypeErrormenzionato. Per risolverlo, usa if(obj === null) {return null}- senza i qoutes intorno null.
veproza

1
Un altro problema: il tuo codice non gestisce la possibilità di "caratteri incorporati nelle stringhe.
Pointy

@Pointy - sì, dovrò aggiungere un po 'di logica per questo ... grazie
zahabba

Risposte:


134

Risposta generica

Questo errore si verifica quando si chiama una funzione che si aspetta un oggetto come argomento, ma si passa invece undefined o null , come ad esempio

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

Poiché di solito è un errore, la soluzione è controllare il codice e correggere la condizione null / undefined in modo che la funzione ottenga un Object appropriato o non venga chiamata affatto.

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

Risposta specifica al codice in questione

La linea if (obj === 'null') { return null;} // null unchanged non valuterà quando data null, solo se data la stringa "null". Quindi, se passi il nullvalore effettivo al tuo script, verrà analizzato nella parte Object del codice. E Object.keys(null)lancia il TypeErrormenzionato. Per risolverlo, usa if(obj === null) {return null}- senza le qoutes intorno a null.


8
Evidenzia: "E Object.keys(null)lancia il TypeErrormenzionato".
falsarella

1
Per aggiungere un altro esempio comune in cui ciò accade: delete obj.propertydoveobj===null
Gio

4

Assicurati che l'oggetto di destinazione non sia vuoto ( nullo undefined).

Puoi inizializzare l'oggetto di destinazione con un oggetto vuoto come di seguito:

var destinationObj = {};

Object.assign(destinationObj, sourceObj);

2

Ciò è molto utile per evitare errori durante l'accesso alle proprietà di oggetti nulli o indefiniti.

null in un oggetto non definito

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 per svuotare l'oggetto

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

0

Ho risolto lo stesso problema in un progetto React Native. L'ho risolto usando questo.

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

0

Nel mio caso, ho aggiunto l'estensione Lucid a Chrome e non ho notato il problema in quel momento. Dopo circa una giornata di lavoro sul problema e capovolgimento del programma, in un post qualcuno aveva menzionato Lucid. Mi sono ricordato cosa avevo fatto e ho rimosso l'estensione da Chrome e ho eseguito di nuovo il programma. Il problema era scomparso. Sto lavorando con React. Ho pensato che questo potrebbe aiutare.


0

Sostituire

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

Se stai usando Laravel , il mio problema era nel nome della mia rotta. Anziché:

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

Scrissi:

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

e quando ho corretto il nome del controller, il codice ha funzionato!


0

Nel mio caso avevo un paio di parentesi in più ()

Invece di

export default connect(
  someVariable
)(otherVariable)()

Doveva essere

export default connect(
  someVariable
)(otherVariable)

0

Lo snippet di seguito è sufficiente per capire come ho riscontrato lo stesso problema ma in uno scenario diverso e come l'ho risolto utilizzando la guida nella risposta accettata. Nel mio caso stavo cercando di registrare le chiavi dell'oggetto presenti nell'indice 0 dell'array 'defaultViewData' utilizzando il metodo Object.keys ().

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

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

Il file console.log non veniva stampato e ricevevo lo stesso errore pubblicato in questa domanda. Per evitare quell'errore ho aggiunto la condizione di seguito

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

L'aggiunta di questo controllo ha assicurato che non ottenessi questo errore. Spero che questo aiuti per qualcuno.

Nota: questo è il codice React.js. (anche se per capire il problema non importa).


-2

Ho lo stesso problema con un elemento in un modulo web. Quindi quello che ho fatto per risolverlo è stato convalidare. if (Object === 'null') fa qualcosa

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.