Não é possível acessar a propriedade do objeto, mesmo que seja exibida em um log do console

329

Abaixo, você pode ver a saída desses dois logs. O primeiro mostra claramente o objeto completo com a propriedade que estou tentando acessar, mas na próxima linha de código não consigo acessá-lo config.col_id_3(consulte o "indefinido" na captura de tela?). Alguém pode explicar isso? Eu posso ter acesso a qualquer outra propriedade, exceto field_id_4também.

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

É isso que essas linhas imprimem no console

Saída do console

Brian Litzinger
fonte
6
você pode tentar console.log(JSON.stringify(config));ans compartilhar o / p
Arun P Johny
2
também tente isso, se isso funcionar console.log (config ['col_id_3']);
zzlalani
5
isso funcionou para mim. usando a saída de string como nova entrada para um objeto de trabalho: JSON.parse (JSON.stringify (obj))
Tope
2
A codificação e a análise não resolveram o problema para mim, por algum motivo. No entanto, a análise direta o fez. JSON.parse(obj)
precisa saber é o seguinte
3
Por alguma razão, todas as respostas explicar como para registrar o objeto sem a chave, não como acessar a chave
remidej

Respostas:

296

A saída de console.log(anObject)é enganosa; o estado do objeto exibido só é resolvido quando você expande o> no console. É não o estado do objeto quando você console.log'd o objeto.

Em vez disso, tente console.log(Object.keys(config)) , ou mesmo, console.log(JSON.stringify(config))e você verá as chaves ou o estado do objeto no momento em que chamou console.log.

Você (normalmente) encontrará as chaves que estão sendo adicionadas após a sua console.logligação.

Matt
fonte
11
Esse comportamento é um bug ou um recurso? Se é um recurso, qual é o raciocínio por trás dele?
ESR
2
Como se contorna isso então? Definir um tempo limite NÃO parece ser uma boa solução.
Sahand
9
Então, como podemos acessar essa propriedade, a partir do objeto?
Rohit Sharma
Para esclarecer, o comportamento do >botão é diferente dependendo se uma matriz está sendo expandida ou um objeto?
Flimm
Ao fazer alguns testes, parece que você se deparou com esse problema, mesmo com uma matriz, então eu recomendaria o JSON.stringify.
Flimm
62

Acabei de ter esse problema com um documento carregado do MongoDB usando o Mongoose .

Ao executar console.log()em todo o objeto, todos os campos do documento (como armazenados no banco de dados) apareceriam. No entanto, alguns acessadores individuais de propriedades retornariam undefinedquando outros (inclusive _id) funcionassem bem.

Descobriu-se que os assessores da propriedade só funciona para os campos especificados na minha mongoose.Schema(...)definição, enquanto que console.log()eJSON.stringify() retorna todos os campos armazenados no banco de dados.

Solução (se você estiver usando o Mongoose) : verifique se todos os seus campos db estão definidos em mongoose.Schema(...).

ramin
fonte
Ótima explicação para esse problema, achei que o Mongoose me permitiria consultar o json sem um esquema (em um script externo), mas impediria gravações. Parece funcionar porque o _id está presente e o console.log diz que todo o resto deve estar acessível, mas não está. Bizarro.
Bstar
7
Acontece que eu estava vendo isso porque JSON.stringify()(e os nós console.log()) alteram seu comportamento se o objeto fornecido tiver uma .toJSON()função. A saída que você vê é o que .toJSON()retorna, e não o objeto original. O Mongoose fornece objetos de modelo com um .toJSON()que fornece o objeto db subjacente. O objeto de modelo possui apenas acessadores para os campos que você define no esquema, mas todos os campos db aparecem quando você o registra, porque na verdade está vendo o objeto subjacente retornado por .toJSON().
Ramp #
Por que o mangusto não permite ler outras propriedades, você tem alguma idéia?
precisa
Isso foi útil para mim ao fazer upload de um CSV no mongodb e buscar a propriedade. Certifique-se de que seus nomes correspondam. Ótima resposta obrigado.
9BallOnTheSnap 25/02/19
1
Obrigado por isso. Eu estava ficando louco vendo isso no console e não conseguindo acessá-lo. Adicionado o valor ao meu esquema e estou pronto para prosseguir. Obrigado novamente!
Alittletf
27

Verifique se dentro do objeto há uma matriz de objetos. Eu tive um problema semelhante com um JSON:

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

Tentei acessar a chave 'name' em 'category' e recebi o erro indefinido , porque estava usando:

var_name = obj_array.terms.category.name

Então eu percebi que ele tem colchetes, o que significa que ele tem uma matriz de objetos dentro da chave de categoria, porque pode ter mais de um objeto de categoria. Então, para obter a chave 'name', usei isso:

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

E isso faz o truque.

Talvez seja tarde demais para esta resposta, mas espero que alguém com o mesmo problema encontre isso como eu antes de encontrar a solução :)

Asaf Lopez
fonte
23

Eu tive o mesmo problema. A solução para mim foi usar a saída stringified como entrada para analisar o JSON. isso funcionou para mim. espero que seja útil para você

var x =JSON.parse(JSON.stringify(obj));
console.log(x.property_actually_now_defined);
Tope
fonte
2
Sim, funcionou, mas por que isso é necessário? Eu já tenho um JSON, por que preciso fazer isso?
jain
@dilpeshjain Não tenho muita certeza, mas arriscaria que já não temos JSON (talvez exista um cenário de carregamento lento, não estou sabendo o suficiente no momento), mas passando o que quer que tenhamos no JSON.stringify requer que uma sequência seja retornada (como a chamada console.log precisa para impressão). Como sei que posso obter pelo menos uma sequência, posso usá-la para criar um objeto JSON com certeza imediatamente.
Top2
4
@jain você precisa isto porque JavaScript é uma linguagem horrível
22

A propriedade que você está tentando acessar talvez ainda não exista. O Console.log funciona porque é executado após um pequeno atraso, mas esse não é o caso do restante do seu código. Tente o seguinte:

var a = config.col_id_3;    //undefined

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

}, 100);
Lai Xue
fonte
1
Eu costumava método onload para obter o meu objeto values.But ainda me dá indefinido no primeiro tempo .. Essa linguagem me faz morto dia após dia
Teoman tingir
uma solução fácil seria implementar uma promessa de inspetor que verifica se a propriedade desejada é definida com setTimeout e resolve + limpa o tempo limite assim que a propriedade se torna disponível.
Lai Xue
Uau. Nos meus 15 anos de programação na web, nunca havia encontrado isso e nunca pensado em como o log do console funciona. Sua resposta ajudou a esclarecer um pouco disso.
Kai Qing
12

No meu caso, eu estava passando um objeto para uma promessa, dentro da promessa estava adicionando mais valores / chave ao objeto e, quando isso foi feito, a promessa retornou o objeto.

No entanto, um pouco da minha parte, a promessa estava retornando o objeto antes de ser totalmente concluído ... assim, o resto do meu código estava tentando processar o objeto atualizado e os dados ainda não estavam lá. Mas, como acima, no console, vi o objeto totalmente atualizado, mas não consegui acessar as chaves - elas estavam voltando indefinidas. Até que eu vi isso:

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*

O [i] é um pequeno ícone, quando passei o mouse sobre ele Object value at left was snapshotted when logged, value below was evaluated just now. Foi quando me ocorreu que meu objeto estava sendo avaliado antes que a promessa o atualizasse completamente.

rolinger
fonte
10

Lutei com esse problema hoje e pensei em deixar uma resposta com minha solução.

Eu estava buscando um objeto de dados via ajax, algo como isto: {"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}

Digamos que esse objeto esteja em uma variável chamada data. Sempre que me referi data.i18n, recebi undefined.

  1. console.log(data) mostrou o objeto como esperado
  2. console.log(Object.keys(data)) disse ["constants","i18n"] como esperado
  3. Renomeando i18n para inter não mudou nada
  4. Eu até tentei mudar os dados para tornar "i18n" o primeiro objeto
  5. Movemos o código para ter certeza absoluta de que o objeto estava completamente definido e não havia nenhum problema com a promessa do ajax.

Nada ajudou ... Então, no lado do servidor, escrevi os dados no log do php, e ele revelou o seguinte:

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

O "i" na chave de índice era na verdade um u0456 (i cirílico). Isso não estava visível no meu editor de php ou no log do console do navegador. Apenas o log php revelou isso ... Isso foi complicado ...

Jette
fonte
1
Este também foi o meu problema; tinha um caractere cirílico 'c' em alguns casos. Encontrei pesquisando no meu arquivo a string que eu esperava; o suspeito não foi selecionado, de modo que me disse que havia um personagem errado que era invisível aos olhos.
knighter
Essa resposta realmente me ajudou a encontrar minha solução. Meu problema foi que eu havia digitado incorretamente meu nome de variável. Eu fiz "atualizar" em vez de "atualizar" lol
Savlon 19/04
8

Meus dados eram apenas json data string. (Esta variável foi armazenada como string json na sessão).

console.log(json_string_object)

-> retorna apenas a representação dessa string e não há como fazer diferença, seja string ou objeto.

Então, para fazê-lo funcionar, eu só precisava convertê-lo novamente em objeto real:

object = JSON.parse(json_string_object);
makkasi
fonte
Esta foi a única resposta que funcionou para mim e também é mencionada nos comentários da pergunta original; isso deve ser maior.
abagh0703
5

Em 2018, a Mozilla nos avisa no Mozilla Docs aqui !

Cito "Objetos de Log" :

Não use console.log(obj);, useconsole.log(JSON.parse(JSON.stringify(obj))); .

Dessa forma, você tem certeza de que está vendo o valor de obj no momento em que o registra.

MTZ
fonte
4

Isso pode ajudar alguém, pois tive um problema semelhante no qual o JSON.parse () estava retornando um objeto que eu poderia imprimir no console.log (), mas não consegui acessar os campos específicos e nenhuma das soluções acima funcionou. mim. Como usar a combinação de JSON.parse () com 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  

Acabei resolvendo o problema usando um analisador diferente fornecido pelo ExtJs Ext.decode ();

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

No meu caso, acontece que mesmo que eu receba os dados no formato de um modelo como myMethod(data:MyModelClass) objeto até que o objeto recebido seja do tipo string. Qual é y no console.log (dados) eu recebo o conteúdo. A solução é apenas analisar o JSON (no meu caso)

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

O pensamento pode ser útil.

Karthikeyan M
fonte
2

Acabei de encontrar esse problema com objetos gerados pelo csv-parser a partir de um arquivo CSV gerado pelo MS Excel. Eu era capaz de acessar todas as propriedades, exceto a primeira propriedade - mas ela apareceria bem se eu escrevesse o objeto inteiro usando o console.log.

Descobriu-se que o formato CSV UTF-8 insere 3 bytes (ef bb bf) no início, correspondendo a um caractere invisível - que estavam sendo incluídos como parte do primeiro cabeçalho da propriedade pelo csv-parser. A solução foi gerar novamente o CSV usando a opção não UTF e isso eliminou o caractere invisível.

Mike Rizzo
fonte
Você é um herói! Obrigado por postar isso. Eu estava puxando meu cabelo.
Jordan S
Obrigado novamente por postar isso! Salvou minha noite!
Oliver Hickman
2

Eu tive um problema semelhante, espero que a seguinte solução ajude alguém.
Você pode usarsetTimeout função como alguns caras sugerem aqui, mas você nunca sabe quanto tempo exatamente o seu navegador precisa para definir seu objeto.

Fora disso, eu sugiro usar a setIntervalfunção. Ele aguardará até que seu objeto config.col_id_3seja definido e, em seguida, disparará sua próxima parte do código que requer suas propriedades 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
fonte
2

se você estiver usando TYPESCRIPTe / ou ANGULAR, pode ser isso!

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

definindo o tipo de resposta para qualquer problema corrigido para mim, não consegui acessar as propriedades na resposta até definir res: any

consulte esta pergunta A propriedade '_body' não existe no tipo 'Response'

russiansummer
fonte
1

Eu tive o mesmo problema e nenhuma solução acima funcionou para mim e, mais tarde, pareceu um palpite. No entanto, agrupar meu código que cria o objeto em uma setTimeoutfunção fez o truque para mim.

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
fonte
1

Eu tive um problema semelhante ou talvez apenas relacionado.

Para o meu caso, eu estava acessando propriedades de um objeto, mas um não estava definido. Descobri que o problema era um espaço em branco no código do lado do servidor ao criar a chave val do objeto.

Minha abordagem foi a seguinte ...

criando meu objeto ... observe o espaço em branco na "palavra"

resposta que recebo da minha API REST

código javascript para registrar os valores

resultados de log do console

Depois de remover o espaço em branco do código do servidor criando o objeto, agora eu podia acessar a propriedade como abaixo ...

resultado após remover o espaço em branco

Esse pode não ser o problema com o caso da questão, mas foi para o meu caso e pode ser para outra pessoa. Espero que ajude.

rey_coder
fonte
1

Acabei de ter o mesmo problema com um documento carregado do MongoDB usando o Mongoose.

Descobri que estou usando a propriedade find()para retornar apenas um objeto, então mudei find()para findOne()e tudo funcionou para mim.

Solução (se você estiver usando o Mongoose): certifique-se de retornar apenas um objeto, para poder analisá object.id-lo ou ele será tratado como uma matriz, para que você precise acessá-lo dessa maneira object[0].id.

Mohamed Hassan Kadri
fonte
1

Para mim, acabou por ser um problema relacionado ao Mongoose.

Eu estava repetindo os objetos que obtive de uma consulta Mongo. Eu apenas tive que remover:

items = await Model.find()

E substitua-o por:

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

Eu tive um problema como esse e achei a solução relacionada ao Underscore.js. Meu log inicial não fazia sentido:

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

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

console.log(obj.code);

> undefined

Encontrei a solução também olhando as chaves do objeto:

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

> ["_wrapped","_chain"]

Isso me levou a perceber que objera realmente um invólucro Underscore.js em torno de um objeto, e a depuração inicial estava mentindo para mim.

Marcus Downing
fonte
0

Eu tive um problema semelhante (ao desenvolver para o SugarCRM), onde começo com:

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);

O problema estava fetch(), sua chamada assíncrona, então eu tive que reescrever meu código em:

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
fonte
0

Caso isso seja útil para alguém, tive um problema semelhante e é porque alguém criou uma substituição para .toJSON no objeto com o qual estava trabalhando. Então o objeto era algo como:

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

Mas .toJSON () era:

toJSON() {
  return this.foo
}

Então, quando chamei JSON.stringify (myObject), ele retornou "{" bar ":" Hello "," baz ":" World "}". No entanto, Object.keys (myObject) revelou o "foo".

emote_control
fonte
toJson()este é o ponto que ninguém mencionou aqui. Não sei por que essa resposta foi recusada, pois essa é uma maneira de criar um objeto que tem um valor diferente de sua representação em json ou console. Eu não sabia que ela existia até que a descobri em uma resposta diferente, e acho que essa resposta deve ser votada, pois é um ponto a ser considerado com esses tipos de problemas.
Rick Love
Considerando o número de respostas que têm exatamente 0 pontos, acho que alguém acabou de votar em tudo.
emote_control 27/02
0

Eu enfrentei o mesmo problema hoje. No meu caso, as chaves estavam aninhadas, ou seja, key1.key2. Dividi as teclas usando split () e depois usei a notação de colchete, que funcionou para mim.

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

Eu dividi as chaves e usei assim, dados [chave1] [chave2] que fizeram o trabalho para mim.

COG
fonte
0

Eu tive o mesmo problema hoje. O problema foi causado por uglify-js. Depois que eu executei o mesmo problema de código não uglificado foi resolvido. Remoção de

--mangle-props

do uglify-js foi suficiente para ter um código uglificado em funcionamento.

Talvez, a melhor prática seja usar algum prefixo para propriedades que precisam ser alteradas com a regra regex para uglify-js.

Aqui está a fonte:

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

e aqui está como foi uglificado:

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

Nenhum dos JSON stringify / parse funcionou para mim.

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

Eu queria o valor de formValues.myKeye o que fez o truque foi um setTimeout 0 como no exemplo abaixo. Espero que ajude.

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

Acabei de encontrar esse problema também e, para encurtar a história, minha API estava retornando um tipo de cadeia de caracteres e não JSON. Portanto, parecia exatamente o mesmo quando você o imprimia no log, no entanto, sempre que eu tentava acessar as propriedades, isso me dava um erro indefinido.

Código da API:

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

anteriormente eu estava voltando:

return Json(string Of object);
Zapnologica
fonte
0

Hoje tive um problema semelhante no React. Eventualmente, percebi que o problema estava sendo causado pelo estado ainda não estar definido. Eu estava ligando user.user.namee, embora estivesse aparecendo no console, não consegui acessá-lo no meu componente até incluir uma verificação para verificar se user.userestava definido e depois ligar user.user.name.

Efiwe
fonte