No se puede acceder a la propiedad del objeto, aunque aparezca en un registro de consola

329

A continuación, puede ver el resultado de estos dos registros. El primero muestra claramente el objeto completo con la propiedad a la que estoy intentando acceder, pero en la siguiente línea de código, no puedo acceder a él config.col_id_3(¿ves el "indefinido" en la captura de pantalla?). ¿Alguien puede explicar esto? Puedo obtener acceso a todas las demás propiedades, excepto field_id_4también.

console.log(config);
console.log(config.col_id_3);

Esto es lo que imprimen estas líneas en la consola

Salida de la consola

Brian Litzinger
fuente
66
¿Puedes probar console.log(JSON.stringify(config));y compartir la o / p
Arun P Johny
2
también intente esto, si esto funciona console.log (config ['col_id_3']);
zzlalani
55
Esto funcionó para mí. utilizando la salida en cadena como nueva entrada para un objeto de trabajo: JSON.parse (JSON.stringify (obj))
Tope
2
Stringificar y luego analizar no resolvió el problema para mí, por alguna razón. Sin embargo, el análisis directo lo hizo. JSON.parse(obj)
JacobPariseau
3
Por alguna razón, todas las respuestas explican cómo registrar el objeto sin la clave, no cómo acceder a la clave
remidej

Respuestas:

296

La salida de console.log(anObject)es engañosa; el estado del objeto que se muestra solo se resuelve cuando expande >en la consola. Es no el estado del objeto cuando se console.log'd del objeto.

En su lugar, intente console.log(Object.keys(config)), o incluso, console.log(JSON.stringify(config))y verá las teclas o el estado del objeto en el momento en que llamó console.log.

Encontrará (generalmente) que las claves se están agregando después de su console.logllamada.

Mate
fuente
11
¿Es este comportamiento un error o una característica? Si es una característica, ¿cuál es el razonamiento detrás de ella?
ESR
2
¿Cómo se puede evitar esto entonces? Establecer un tiempo de espera NO parece una buena solución.
Sahand
99
Entonces, ¿cómo podemos acceder a esta propiedad, desde el objeto?
Rohit Sharma
Para aclarar, ¿el comportamiento del >botón es diferente dependiendo de si una matriz se está expandiendo o un objeto?
Flimm
Al hacer algunas pruebas, parece que te has encontrado con este problema incluso con una matriz, por lo que recomendaría hacer JSON.stringify en su lugar.
Flimm
62

Acabo de tener este problema con un documento cargado desde MongoDB usando Mongoose .

Cuando se ejecuta console.log()en todo el objeto, aparecerían todos los campos del documento (como se almacenan en la base de datos). Sin embargo, algunos accesores de propiedades individuales regresarían undefined, cuando otros (incluidos _id) funcionaron bien.

Resultó que los accesores de propiedad solo funcionan para los campos especificados en mi mongoose.Schema(...)definición, mientras que console.log()y JSON.stringify()devuelve todos los campos almacenados en la base de datos.

Solución (si está usando Mongoose) : asegúrese de que todos sus campos db estén definidos mongoose.Schema(...).

ramin
fuente
Gran explicación de este problema, pensé que Mongoose me dejaría consultar el json sin un esquema (en un script externo), pero evitaría las escrituras. Parece funcionar porque _id está presente y console.log dice que todo lo demás debería ser accesible, pero no lo es. Extraño.
bstar
77
Resulta que estaba viendo esto porque JSON.stringify()(y Node's console.log()) cambian su comportamiento si el objeto dado tiene una .toJSON()función. El resultado que ve es lo que .toJSON()devuelve, y no el objeto original. Mongoose te da objetos modelo con un .toJSON()que da el objeto db subyacente. El objeto modelo solo tiene accesores para los campos que define en el esquema, pero luego todos los campos db aparecen cuando lo registra porque realmente está viendo el objeto subyacente devuelto por .toJSON().
ramin
¿Por qué la mangosta no permite leer otras propiedades? ¿Tienes alguna idea?
Kannan T
Esto fue útil para mí cuando cargué un CSV en mongodb y busqué la propiedad. Asegúrate de que tus nombres coincidan. Gran respuesta gracias.
9BallOnTheSnap
1
Gracias por esto. Me estaba volviendo loco al verlo en la consola y no poder acceder a él. Agregué el valor a mi esquema y estoy listo para comenzar. ¡Gracias de nuevo!
alittletf
27

Compruebe si dentro del objeto hay una matriz de objetos. Tuve un problema similar con un JSON:

    "terms": {
        "category": [
            {
                "ID": 4,
                "name": "Cirugia",
                "slug": "cirugia",
                "description": "",
                "taxonomy": "category",
                "parent": null,
                "count": 68,
                "link": "http://distritocuatro.mx/enarm/category/cirugia/"
            }
        ]
    }

Traté de acceder a la clave 'nombre' desde 'categoría' y obtuve el error indefinido , porque estaba usando:

var_name = obj_array.terms.category.name

Luego me di cuenta de que tiene corchetes, lo que significa que tiene una matriz de objetos dentro de la clave de categoría, porque puede tener más de un objeto de categoría. Entonces, para obtener la clave 'nombre', utilicé esto:

var_name = obj_array.terms.category[0].name

Y eso hace el truco.

Tal vez sea demasiado tarde para esta respuesta, pero espero que alguien con el mismo problema lo encuentre antes que encontrar la solución :)

Asaf Lopez
fuente
23

Tuve el mismo problema. La solución para mí fue usar la salida en cadena como entrada para analizar el JSON. Esto funcionó para mí. espero que te sea útil

var x =JSON.parse(JSON.stringify(obj));
console.log(x.property_actually_now_defined);
Emborracharse
fuente
2
Sí, funcionó, pero ¿por qué se requiere esto? Ya tengo un JSON, ¿por qué necesito hacer esto?
Jain
@dilpeshjain No estoy exactamente seguro, pero me atrevería a decir que ya no tenemos JSON (tal vez hay un escenario de tipo de carga perezosa en curso, no estoy lo suficientemente informado sobre eso en este momento), pero pasando lo que tenemos en JSON.stringify requiere que se devuelva una cadena (como la llamada a console.log necesita para imprimir). Como sé que al menos puedo obtener una cadena, entonces puedo usar esa cadena para crear un objeto JSON con seguridad de inmediato.
Tope
44
@jain necesitas esto porque JavaScript es un lenguaje horrible
22

Es posible que la propiedad a la que intentas acceder todavía no exista. Console.log funciona porque se ejecuta después de un pequeño retraso, pero ese no es el caso para el resto de su código. Prueba esto:

var a = config.col_id_3;    //undefined

setTimeout(function()
{
    var a = config.col_id_3;    //voila!

}, 100);
Lai Xue
fuente
1
Solía ​​cargar el método para obtener los valores de mis objetos. Pero aún no me define por primera vez ... Este lenguaje me hace morir día a día
Teoman Tıngır
una solución fácil sería implementar una promesa de observador que verifique si la propiedad deseada se define con setTimeout y resuelve + borra el tiempo de espera una vez que la propiedad esté disponible.
Lai Xue
Guau. En mis 15 años de programación web nunca me había encontrado con esto y nunca pensé en cómo funciona el registro de la consola. Su respuesta ayudó a aclarar algo de eso.
Kai Qing
12

En mi caso, estaba pasando un objeto a una promesa, dentro de la promesa estaba agregando más claves / valores al objeto y cuando se hizo, la promesa devolvió el objeto.

Sin embargo, una ligera mirada de mi parte, la promesa era devolver el objeto antes de que estuviera completamente terminado ... por lo tanto, el resto de mi código estaba tratando de procesar el objeto actualizado y los datos aún no estaban allí. Pero como en el caso anterior, en la consola, vi el objeto completamente actualizado, pero no pude acceder a las teclas, volvían indefinidas. Hasta que vi esto:

console.log(obj) ;
console.log(obj.newKey1) ;

// returned in console
> Object { origKey1: "blah", origKey2: "blah blah"} [i]
    origKey1: "blah"
    origKey2: "blah blah"
    newKey1: "this info"
    newKey2: "that info"
    newKey3: " more info"
> *undefined*

El [i] es un pequeño ícono, cuando lo pasé sobre él decía Object value at left was snapshotted when logged, value below was evaluated just now. Fue entonces cuando se me ocurrió que mi objeto estaba siendo evaluado antes de que la promesa lo hubiera actualizado por completo.

Rolinger
fuente
10

Luché con este problema hoy, y pensé que dejaría una respuesta con mi solución.

Estaba buscando un objeto de datos a través de ajax, algo como esto: {"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}

Digamos que este objeto está en una variable llamada datos. Cada vez que hice referencia data.i18nme dieron undefined.

  1. console.log(data) mostró el objeto como se esperaba
  2. console.log(Object.keys(data)) dijo ["constants","i18n"] como se esperaba
  3. Cambiar el nombre de i18n a inter no cambió nada
  4. Incluso intenté cambiar los datos para hacer de "i18n" el primer objeto
  5. Se movió el código para asegurarse absolutamente de que el objeto estaba completamente configurado y no había ningún problema con la promesa de ajax.

Nada ayudó ... Luego, en el lado del servidor, escribí los datos en el registro de php, y reveló esto:

{"constants": {"value1":"x","value2":"y"},"\u045618n" {"data1":"x", "data2":"y"}}

La "i" en la clave de índice era en realidad un u0456 (cirílico i). Esto no estaba visible en mi editor php o en el registro de la consola del navegador. Solo el registro de php reveló esto ... Eso fue complicado ...

Jette
fuente
1
Este también fue mi problema; tenía un carácter cirílico 'c' en su lugar en algunas de las instancias. Lo encontré buscando en mi archivo la cadena que esperaba; el sospechoso no fue seleccionado, así que eso me dijo que había un personaje incorrecto que era invisible a la vista.
caballero
Esta respuesta realmente me ayudó a encontrar mi solución. Mi problema fue que había escrito mal mi nombre de variable. Hice "udpate" en lugar de "actualizar" lol
Savlon
8

Mis datos eran solo cadenas de datos json. (Esta variable se almacenó como cadena json en la sesión).

console.log(json_string_object)

-> devuelve solo la representación de esta cadena y no hay forma de diferenciar si es cadena u objeto.

Entonces, para que funcione, solo necesitaba convertirlo de nuevo a objeto real:

object = JSON.parse(json_string_object);
makkasi
fuente
Esta fue la única respuesta que funcionó para mí y también se menciona en los comentarios de la pregunta original, esta debería ser mayor.
abagh0703
5

En 2018, Mozilla nos advierte en los documentos de Mozilla aquí !

Cito "Logging Objects" :

No uses console.log(obj);, usaconsole.log(JSON.parse(JSON.stringify(obj))); .

De esta manera, está seguro de que está viendo el valor de obj en el momento en que lo registra.

MTZ
fuente
4

Esto podría ayudar a alguien ya que tuve un problema similar en el que JSON.parse () estaba devolviendo un objeto que podía imprimir en console.log () pero no pude acceder a los campos específicos y ninguna de las soluciones anteriores funcionó yo. Como usar la combinación de JSON.parse () con JSON.stringify ().

var jsonObj = JSON.parse(JSON.stringify(responseText))

// where responseText is a JSON String returned by the server.

console.log(jsonObj) ///Was printing the object correctly
console.log(jsonObj.Body) /// Was printing Undefined  

Terminé resolviendo el problema usando un analizador diferente proporcionado por ExtJs Ext.decode ();

var jsonObj = Ext.decode(responseText)
console.log(jsonObj.Body) //Worked...
user_CC
fuente
2

En mi caso, resulta que a pesar de que recibo los datos en el formato de un modelo como myMethod(data:MyModelClass) objeto hasta que el objeto recibido era de tipo cadena. Que es y en console.log (data) obtengo el contenido. La solución es solo analizar el JSON (en mi caso)

const model:MyMOdelClass=JSON.parse(data);

El pensamiento puede ser útil.

Karthikeyan M
fuente
2

Acabo de encontrar este problema con los objetos generados por csv-parser a partir de un archivo CSV que fue generado por MS Excel. Pude acceder a todas las propiedades excepto a la primera propiedad, pero aparecería bien si escribiera todo el objeto usando console.log.

Resultó que el formato CST UTF-8 inserta 3 bytes (ef bb bf) al inicio correspondiente a un carácter invisible, que se incluyó como parte del primer encabezado de propiedad por csv-parser. La solución fue volver a generar el CSV utilizando la opción no UTF y esto eliminó el carácter invisible.

Mike Rizzo
fuente
¡Usted es un héroe! Gracias por publicar esto. Me estaba sacando el pelo.
Jordan S
¡Gracias de nuevo por publicar esto! Salvó mi noche!
Oliver Hickman el
2

He tenido un problema similar, espero que la siguiente solución ayude a alguien.
Puedes usarsetTimeout función como sugieren algunos tipos aquí, pero nunca se sabe exactamente cuánto tiempo necesita su navegador para definir su objeto.

Fuera de eso, sugeriría usar la setIntervalfunción en su lugar. Esperará hasta que su objeto config.col_id_3se defina y luego disparará su siguiente parte de código que requiere sus propiedades de objeto específicas.

window.addEventListener('load', function(){

    var fileInterval = setInterval(function() {
        if (typeof config.col_id_3 !== 'undefined') {

            // do your stuff here

            clearInterval(fileInterval); // clear interval
        }
    }, 100); // check every 100ms

});
Lefan
fuente
2

si estás usando TYPESCRIPTy / o ANGULAR, ¡podría ser esto!

.then((res: any) => res.json())

ajustar el tipo de respuesta a cualquier fijo este problema para mí, no pude acceder a las propiedades de la respuesta hasta que establecer res: cualquier

vea esta pregunta La propiedad '_body' no existe en el tipo 'Respuesta'

verano ruso
fuente
1

Tuve el mismo problema y ninguna de las soluciones anteriores funcionó para mí y de alguna manera se sintió como adivinar a partir de entonces. Sin embargo, envolver mi código que crea el objeto en una setTimeoutfunción fue el truco para mí.

setTimeout(function() {
   var myObj = xyz; //some code for creation of complex object like above
   console.log(myObj); // this works
   console.log(myObj.propertyName); // this works too
});
Tushar Shukla
fuente
1

Tuve un problema similar o tal vez solo relacionado.

Para mi caso, estaba accediendo a las propiedades de un objeto pero uno no estaba definido. Encontré que el problema era un espacio en blanco en el código del lado del servidor al crear la clave, val del objeto.

Mi enfoque fue el siguiente ...

creando mi objeto ... observe el espacio en blanco en "palabra"

respuesta que recibo de mi API REST

código javascript para registrar los valores

registrar resultados de la consola

Después de eliminar el espacio en blanco del código del lado del servidor que crea el objeto, ahora podía acceder a la propiedad de la siguiente manera ...

resultado después de eliminar espacios en blanco

Este podría no ser el problema con el caso de la pregunta del tema, pero fue para mi caso y puede serlo para alguien más. Espero eso ayude.

rey_coder
fuente
1

Acabo de tener el mismo problema con un documento cargado desde MongoDB usando Mongoose.

Resultó que estoy usando la propiedad find()para devolver solo un objeto, así que cambié find()afindOne() y todo funcionó para mí.

Solución (si está usando Mongoose): asegúrese de devolver un solo objeto, para que pueda analizarlo object.ido se lo tratará como una matriz, por lo que debe acceder de esa manera object[0].id.

Mohamed Hassan Kadri
fuente
1

Para mí resultó ser un problema relacionado con la mangosta.

Estaba recorriendo objetos que obtuve de una consulta de Mongo. Solo tuve que eliminar:

items = await Model.find()

Y reemplazarlo por:

items = await Model.find().lean()
remidej
fuente
0

Tuve un problema como este y descubrí que la solución tenía que ver con Underscore.js. Mi registro inicial no tenía sentido:

console.log(JSON.stringify(obj, null, 2));

> {
>   "code": "foo"
> }

console.log(obj.code);

> undefined

Encontré la solución también mirando las claves del objeto:

console.log(JSON.stringify(Object.keys(obj)));

> ["_wrapped","_chain"]

Esto me llevó a darme cuenta de que en objrealidad era un envoltorio Underscore.js alrededor de un objeto, y la depuración inicial me estaba mintiendo.

Marcus Downing
fuente
0

Tuve un problema similar (cuando desarrollé para SugarCRM), donde comienzo con:

var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});

// This should load object with attributes 
leadBean.fetch();

// Here were my attributes filled in with proper values including name
console.log(leadBean);

// Printed "undefined"
console.log(leadBean.attributes.name);

El problema estaba en fetch()su llamada asíncrona, así que tuve que volver a escribir mi código en:

var leadBean = app.data.createBean('Leads', {id: this.model.attributes.parent_id});

// This should load object with attributes 
leadBean.fetch({
    success: function (lead) {
        // Printed my value correctly
        console.log(lead.attributes.name);
    }
});
Mariyo
fuente
0

En caso de que esto sea útil para alguien, tuve un problema similar, y es porque alguien creó una anulación para .toJSON en el objeto con el que estaba trabajando. Entonces el objeto era algo así como:

{
  foo: {
         bar: "Hello"
         baz: "World"
       }
}

Pero .toJSON () fue:

toJSON() {
  return this.foo
}

Entonces, cuando llamé a JSON.stringify (myObject), devolvió "{" bar ":" Hola "," baz ":" Mundo "}". Sin embargo, Object.keys (myObject) reveló el "foo".

emote_control
fuente
toJson()Este es el punto que nadie ha mencionado aquí. No sé por qué esta respuesta fue rechazada, ya que esta es una forma de crear un objeto que tiene un valor diferente de su representación json o consola. No sabía que existía hasta que lo descubrí en una respuesta diferente, y creo que esta respuesta debería ser votada ya que es un punto a considerar con este tipo de problemas.
Rick Love
Teniendo en cuenta la cantidad de respuestas que tienen exactamente 0 puntos, creo que alguien acaba de votar en contra de todo.
emote_control
0

Me enfrenté al mismo problema hoy. En mi caso, las claves estaban anidadas, es decir, key1.key2. Dividí las teclas usando split () y luego usé la notación de corchetes, que funcionó para mí.

var data = {
    key1: {
          key2: "some value"
       }
}

Dividí las claves y las usé así, datos [clave1] [clave2] que hicieron el trabajo por mí.

DIENTE
fuente
0

Tuve el mismo problema hoy. El problema fue causado por uglify-js. Después de ejecutar el mismo problema de código no uglified, se resolvió. Eliminación de

--mangle-props

desde uglify-js fue suficiente para tener código uglified en funcionamiento.

Quizás, la mejor práctica es usar algún prefijo para las propiedades que tienen que ser modificadas con la regla regex para uglify-js.

Aquí está la fuente:

var data = JSON.parse( content);
...
this.pageIndex = parseInt(data.index);
this.pageTotal = parseInt(data.total);
this.pageLimit = parseInt(data.limit); 

y así es como se uglificó:

var n = JSON.parse( t);
...
this._ = parseInt(n.index), this.g = parseInt(n.total), this.D = parseInt(n.C)
Ilja Kartašov
fuente
0

Ninguno de los JSON stringify / parse funcionó para mí.

formValues.myKey:               undefined
formValues.myKey with timeout:  content

Quería el valor de formValues.myKeyy lo que hizo el truco fue un setTimeout 0 como en el ejemplo a continuación. Espero eso ayude.

console.log('formValues.myKey: ',formValues.myKey);
setTimeout( () => { 
  console.log('formValues.myKey with timeout: ', formValues.myKey);
}, 0 );
anacampesan
fuente
0

También me encontré con este problema, y ​​para resumir, mi API estaba devolviendo un tipo de cadena y no JSON. Así que se veía exactamente igual cuando lo imprimiste en el registro; sin embargo, cada vez que intentaba acceder a las propiedades me daba un error indefinido.

Código API:

     var response = JsonConvert.DeserializeObject<StatusResult>(string Of object);
     return Json(response);

anteriormente solo volvía:

return Json(string Of object);
Zapnologica
fuente
0

Tuve un problema similar hoy en React. Eventualmente me di cuenta de que el problema estaba siendo causado por el estado que aún no se había establecido. Estaba llamando user.user.namey, aunque aparecía en la consola, parecía que no podía acceder a él en mi componente hasta que incluí un cheque para verificar si user.userestaba configurado y luego llamé user.user.name.

Efiwe
fuente