Impossible d'accéder à la propriété d'objet, même si elle apparaît dans un journal de console


329

Ci-dessous, vous pouvez voir la sortie de ces deux journaux. Le premier montre clairement l'objet complet avec la propriété que j'essaie d'accéder, mais sur la ligne de code suivante, je ne peux pas y accéder avec config.col_id_3(voir le "non défini" dans la capture d'écran?). Quelqu'un peut-il expliquer cela? Je peux accéder à toutes les autres propriétés sauf field_id_4aussi.

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

Voici ce que ces lignes impriment dans la console

Sortie console


6
pouvez-vous essayer console.log(JSON.stringify(config));et partager l'o / p
Arun P Johny

2
essayez également ceci, si cela fonctionne console.log (config ['col_id_3']);
zzlalani

5
cela a fonctionné pour moi. en utilisant une sortie stringified comme nouvelle entrée pour un objet de travail: JSON.parse (JSON.stringify (obj))
Tope

2
Stratifié puis analysé n'a pas résolu le problème pour moi, pour une raison quelconque. Cependant l'analyse syntaxique l'a fait. JSON.parse(obj)
JacobPariseau

3
Pour une raison quelconque, toutes les réponses expliquent comment enregistrer l'objet sans la clé, pas comment accéder à la clé
remidej

Réponses:


296

La sortie de console.log(anObject)est trompeuse; l'état de l'objet affiché n'est résolu que lorsque vous développez le >dans la console. Ce n'est pas l'état de l'objet lorsque vous console.logl' auriez fait .

Au lieu de cela, essayez console.log(Object.keys(config))ou même console.log(JSON.stringify(config))et vous verrez les clés ou l'état de l'objet au moment où vous avez appelé console.log.

Vous constaterez (généralement) que les clés sont ajoutées après votre console.logappel.


11
Ce comportement est-il un bug ou une fonctionnalité? Si c'est une fonctionnalité, quel est le raisonnement derrière cela?
ESR

2
Comment contourner cela alors? La définition d'un délai d'attente ne semble PAS être une bonne solution.
Sahand

9
Alors, comment pouvons-nous accéder à cette propriété, à partir de l'objet?
Rohit Sharma

Pour clarifier, le comportement du >bouton est-il différent selon qu'un tableau est en cours d'extension ou un objet?
Flimm

En faisant des tests, il semble que vous ayez rencontré ce problème même avec un tableau, donc je recommanderais plutôt de faire JSON.stringify.
Flimm

62

Je viens d'avoir ce problème avec un document chargé à partir de MongoDB à l'aide de Mongoose .

Lors de l'exécution console.log()sur l'objet entier, tous les champs du document (tels que stockés dans la base de données) s'afficheraient. Cependant, certains accesseurs de propriété individuels reviendraient undefined, alors que d'autres (y compris _id) fonctionnaient bien.

Il s'est avéré que les accesseurs de propriété ne fonctionnent que pour les champs spécifiés dans ma mongoose.Schema(...)définition, console.log()et JSON.stringify()retournent tous les champs stockés dans la base de données.

Solution (si vous utilisez Mongoose) : assurez-vous que tous vos champs db sont définis dans mongoose.Schema(...).


Excellente explication de ce problème, j'ai pensé que Mongoose me laisserait interroger le json sans schéma (dans un script externe), mais empêcherait les écritures. Il semble fonctionner parce que le _id est présent et le console.log indique que tout le reste devrait être accessible, mais ne l'est pas. Bizarre.
bstar

7
Il s'avère que je voyais cela parce que JSON.stringify()(et les nœuds console.log()) changent de comportement si l'objet donné a une .toJSON()fonction. La sortie que vous voyez est ce qui .toJSON()retourne, et non l'objet d'origine. Mongoose vous donne des objets de modèle avec un .toJSON()qui donne l'objet db sous-jacent. L'objet modèle n'a que des accesseurs pour les champs que vous définissez dans le schéma, mais tous les champs db apparaissent alors lorsque vous le connectez car vous voyez réellement l'objet sous-jacent renvoyé par .toJSON().
ramin

Pourquoi la mangouste ne permet-elle pas de lire d'autres propriétés, avez-vous une idée?
Kannan T

Cela m'a été utile lors du téléchargement d'un fichier CSV dans mongodb et de la récupération de la propriété. Assurez-vous que vos noms correspondent. Excellente réponse merci.
9BallOnTheSnap

1
Merci pour ça. J'étais fou de le voir dans la console et de ne pas pouvoir y accéder. J'ai ajouté de la valeur à mon schéma et je suis prêt à partir. Merci encore!
alittletf

27

Vérifiez s'il y a à l'intérieur de l'objet un tableau d'objets. J'ai eu un problème similaire avec un JSON:

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

J'ai essayé d'accéder à la clé 'nom' de 'catégorie' et j'ai eu l' erreur non définie , car j'utilisais:

var_name = obj_array.terms.category.name

Ensuite, j'ai réalisé qu'il avait des crochets, ce qui signifie qu'il avait un tableau d'objets à l'intérieur de la clé de catégorie, car il pouvait avoir plus d'un objet de catégorie. Donc, pour obtenir la clé «nom», j'ai utilisé ceci:

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

Et cela fait l'affaire.

Peut-être qu'il est trop tard pour cette réponse, mais j'espère que quelqu'un avec le même problème trouvera cela comme je l'ai fait avant de trouver la solution :)


23

J'ai eu le même problème. La solution pour moi était d'utiliser la sortie stringifiée comme entrée pour analyser le JSON. cela a fonctionné pour moi. j'espère que cela vous est utile

var x =JSON.parse(JSON.stringify(obj));
console.log(x.property_actually_now_defined);

2
Oui, cela a fonctionné, mais pourquoi est-ce nécessaire? J'ai déjà un JSON, pourquoi dois-je le faire?
jain

@dilpeshjain Je ne suis pas exactement sûr, mais je suppose que nous n'avons pas déjà JSON (peut-être qu'il y a un scénario de type de chargement paresseux en cours, je ne suis pas assez informé à ce sujet pour le moment), mais en passant tout ce que nous avons dans JSON.stringify nécessite le retour d'une chaîne (comme les besoins de l'appel console.log pour l'impression). Parce que je sais que je peux au moins obtenir une chaîne, alors je peux utiliser cette chaîne pour créer un objet JSON à coup sûr tout de suite.
Tope

4
@jain vous en avez besoin car javascript est une langue horrible

22

La propriété à laquelle vous essayez d'accéder n'existe peut-être pas encore. Console.log fonctionne car il s'exécute après un petit délai, mais ce n'est pas le cas pour le reste de votre code. Essaye ça:

var a = config.col_id_3;    //undefined

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

}, 100);

1
J'avais l'habitude de charger la méthode pour obtenir les valeurs de mes objets. Mais cela me donne toujours undefined à la première fois .. Cette langue me fait mourir de jour en jour
Teoman Tıngır

une solution simple serait d'implémenter une promesse d'observateur qui vérifie si la propriété souhaitée est définie avec setTimeout et résout + efface le délai une fois que la propriété est disponible.
Lai Xue

Sensationnel. Au cours de mes 15 années de programmation Web, je n'avais jamais rencontré cela et n'avais jamais réfléchi au fonctionnement du journal de la console. Votre réponse a aidé à clarifier une partie de cela.
Kai Qing

12

Dans mon cas, je passais un objet à une promesse, dans la promesse j'ajoutais plus de clés / valeurs à l'objet et quand c'était fait, la promesse renvoyait l'objet.

Cependant, un léger coup d'œil de ma part, la promesse était de retourner l'objet avant qu'il ne soit complètement terminé ... ainsi le reste de mon code essayait de traiter l'objet mis à jour et les données n'étaient pas encore là. Mais comme ci-dessus, dans la console, j'ai vu l'objet entièrement mis à jour mais je n'ai pas pu accéder aux clés - elles revenaient indéfinies. Jusqu'à ce que je voie ceci:

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*

Le [i] est une petite icône, quand je l'ai survolé, il a dit Object value at left was snapshotted when logged, value below was evaluated just now. C'est quand il m'est venu à l'esprit que mon objet était en cours d'évaluation avant que la promesse ne l'ait entièrement mis à jour.


10

J'ai eu du mal avec ce problème aujourd'hui et j'ai pensé laisser une réponse avec ma solution.

J'allais chercher un objet de données via ajax, quelque chose comme ceci: {"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}

Supposons que cet objet se trouve dans une variable appelée données. Chaque fois que je faisais référence, data.i18nj'obtenais undefined.

  1. console.log(data) a montré l'objet comme prévu
  2. console.log(Object.keys(data))dit ["constants","i18n"]comme prévu
  3. Renommer i18n en inter n'a rien changé
  4. J'ai même essayé de changer les données pour faire de "i18n" le premier objet
  5. Déplacement du code pour vous assurer que l'objet était complètement défini et qu'il n'y avait aucun problème avec la promesse ajax.

Rien n'a aidé ... Ensuite, côté serveur, j'ai écrit les données dans le journal php, et cela a révélé ceci:

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

Le "i" dans la clé d'index était en fait un u0456 (cyrillique i). Ce n'était pas visible dans mon éditeur php ou le journal de la console du navigateur. Seul le journal php a révélé cela ... C'était difficile ...


1
C'était aussi mon problème; avait plutôt un caractère cyrillique «c» dans certains cas. Je l'ai trouvé en recherchant dans mon fichier la chaîne que j'attendais; le suspect n'a pas été sélectionné, ce qui m'a dit qu'il y avait un mauvais personnage invisible à l'œil.
chevalier

Cette réponse m'a en fait aidé à trouver ma solution. Mon problème était que j'avais mal orthographié mon nom de variable. J'ai fait "udpate" au lieu de "update" lol
Savlon

8

Mes données n'étaient qu'une chaîne de données json. (Cette variable a été stockée sous forme de chaîne json dans la session).

console.log(json_string_object)

-> renvoie uniquement la représentation de cette chaîne et il n'y a aucun moyen de faire la différence entre chaîne et objet.

Donc, pour le faire fonctionner, je devais juste le reconvertir en objet réel:

object = JSON.parse(json_string_object);

C'était la seule réponse qui a fonctionné pour moi et est également mentionnée dans les commentaires de la question d'origine, cela devrait être plus élevé.
abagh0703

5

En 2018, Mozilla nous avertit dans les documents Mozilla ici !

Je cite "Logging Objects" :

N'utilisez pas console.log(obj);, utilisez console.log(JSON.parse(JSON.stringify(obj)));.

De cette façon, vous êtes sûr de voir la valeur de obj au moment où vous le connectez.


4

Cela pourrait aider quelqu'un car j'avais un problème similaire dans lequel JSON.parse () renvoyait un objet que je pouvais imprimer sur la console.log () mais je ne pouvais pas accéder aux champs spécifiques et aucune des solutions ci-dessus ne fonctionnait pour moi. Comme utiliser la combinaison de JSON.parse () avec 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  

J'ai fini par résoudre le problème en utilisant un analyseur différent fourni par ExtJs Ext.decode ();

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

2

Dans mon cas, il se trouve que même si je reçois les données au format d'un myMethod(data:MyModelClass) objet modèle jusqu'à ce que l'objet reçu soit de type chaîne. Qui est y dans console.log (données), j'obtiens le contenu. La solution consiste simplement à analyser le JSON (dans mon cas)

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

La pensée peut être utile.


2

Je viens de rencontrer ce problème avec des objets générés par csv-parser à partir d'un fichier CSV généré par MS Excel. J'ai pu accéder à toutes les propriétés à l'exception de la première propriété - mais cela apparaîtrait bien si j'écrivais tout l'objet à l'aide de console.log.

Il s'est avéré que le format CSV UTF-8 insère au début 3 octets (ef bb bf) correspondant à un caractère invisible - qui étaient inclus dans le premier en-tête de propriété par csv-parser. La solution était de recréer le CSV en utilisant l'option non-UTF et cela a éliminé le caractère invisible.


Vous êtes un héros! Merci d'avoir posté ça. J'arrachais mes cheveux.
Jordan S

Merci encore d'avoir posté ça! Sauvé ma nuit!
Oliver Hickman

2

J'ai eu un problème similaire, j'espère que la solution suivante aide quelqu'un.
Vous pouvez utiliser la setTimeoutfonction comme certains gars le suggèrent ici, mais vous ne savez jamais exactement combien de temps votre navigateur a besoin pour définir votre objet.

En dehors de cela, je suggère d'utiliser la setIntervalfonction à la place. Il attendra que votre objet config.col_id_3soit défini, puis déclenchera votre prochaine partie de code qui nécessite vos propriétés d'objet spécifiques.

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

});

2

si vous utilisez TYPESCRIPTet / ou ANGULAR, ça pourrait être ça!

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

en définissant le type de réponse sur n'importe quel problème résolu pour moi, je ne pouvais pas accéder aux propriétés de la réponse jusqu'à ce que je définisse res: any

voir cette question La propriété '_body' n'existe pas sur le type 'Response'


1

J'ai eu le même problème et aucune solution ci-dessus n'a fonctionné pour moi et cela ressemblait à un travail de devinette par la suite. Cependant, encapsuler mon code qui crée l'objet dans une setTimeoutfonction a fait l'affaire pour moi.

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

1

J'ai eu un problème similaire ou peut-être simplement lié.

Pour mon cas, j'accédais aux propriétés d'un objet mais un n'était pas défini. J'ai trouvé que le problème était un espace blanc dans le code côté serveur lors de la création de la clé, val de l'objet.

Mon approche était la suivante ...

création de mon objet ... remarquez l'espace blanc dans "word"

réponse que j'obtiens de mon API REST

code javascript pour enregistrer les valeurs

journal des résultats de la console

Après avoir supprimé l'espace blanc du code côté serveur créant l'objet, je pouvais maintenant accéder à la propriété comme ci-dessous ...

résultat après avoir supprimé les espaces

Ce n'est peut-être pas le problème avec le cas de la question, mais c'était pour mon cas et peut-être pour quelqu'un d'autre. J'espère que ça aide.


1

Je viens d'avoir le même problème avec un document chargé à partir de MongoDB à l'aide de Mongoose.

Il s'est avéré que j'utilise la propriété find()pour renvoyer un seul objet, j'ai donc changé find()pour findOne()et tout a fonctionné pour moi.

Solution (si vous utilisez Mongoose): assurez-vous de renvoyer un seul objet, de sorte que vous puissiez analyser son object.idou il sera traité comme un tableau, vous devez donc y accéder comme ça object[0].id.


1

Pour moi, cela s'est avéré être un problème lié à la mangouste.

Je faisais une boucle sur des objets que j'ai obtenus d'une requête Mongo. Je devais juste retirer:

items = await Model.find()

Et remplacez-le par:

items = await Model.find().lean()

0

J'ai eu un problème comme celui-ci et j'ai trouvé que la solution était de faire avec Underscore.js. Mon enregistrement initial n'avait aucun sens:

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

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

console.log(obj.code);

> undefined

J'ai trouvé la solution en regardant également les clés de l'objet:

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

> ["_wrapped","_chain"]

Cela m'a amené à réaliser qu'il objs'agissait en fait d'un wrapper Underscore.js autour d'un objet, et le débogage initial me mentait.


0

J'ai eu un problème similaire (lors du développement de SugarCRM), où je commence par:

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

Le problème était fetch(), son appel asynchrone donc j'ai dû réécrire mon code dans:

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

0

Juste au cas où cela serait utile pour quelqu'un, j'ai eu un problème similaire, et c'est parce que quelqu'un a créé un remplacement pour .toJSON dans l'objet avec lequel je travaillais. Donc, l'objet était quelque chose comme:

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

Mais .toJSON () était:

toJSON() {
  return this.foo
}

Ainsi, lorsque j'ai appelé JSON.stringify (myObject), il a renvoyé "{" bar ":" Hello "," baz ":" World "}". Cependant, Object.keys (myObject) a révélé le "foo".


toJson()c'est le point que personne n'a mentionné ici. Je ne sais pas pourquoi cette réponse a été rejetée car c'est un moyen de créer un objet qui a une valeur différente de sa représentation json ou console. Je ne savais pas qu'elle existait jusqu'à ce que je la découvre dans une réponse différente, et je pense que cette réponse devrait être augmentée car c'est un point à considérer avec ce type de problèmes.
Rick Love

Compte tenu du nombre de réponses qui ont exactement 0 point, je pense que quelqu'un vient de tout voter.
emote_control

0

J'ai fait face au même problème aujourd'hui. Dans mon cas, les clés étaient imbriquées, c'est-à-dire key1.key2. J'ai divisé les clés en utilisant split (), puis j'ai utilisé la notation entre crochets, qui a fonctionné pour moi.

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

J'ai divisé les clés et les ai utilisées comme ceci, les données [key1] [key2] qui ont fait le travail pour moi.


0

J'ai eu le même problème aujourd'hui. Le problème a été causé par uglify-js. Après avoir exécuté le même problème de code non uglifié, il a été résolu. Suppression de

--mangle-props

de uglify-js suffisait pour avoir du code uglified fonctionnel.

Peut-être, la meilleure pratique consiste à utiliser un préfixe pour les propriétés qui doivent être modifiées avec la règle d'expression régulière pour uglify-js.

Voici la source:

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

et voici comment il a été uglifié:

var n = JSON.parse( t);
...
this._ = parseInt(n.index), this.g = parseInt(n.total), this.D = parseInt(n.C)

0

Aucun des JSON stringify / parse n'a fonctionné pour moi.

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

Je voulais la valeur de formValues.myKeyet ce qui a fait l'affaire était un setTimeout 0 comme dans l'exemple ci-dessous. J'espère que ça aide.

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

0

Je viens de rencontrer ce problème également, et pour faire court, mon API renvoyait un type de chaîne et non JSON. Donc, il avait exactement la même apparence lorsque vous l'imprimiez dans le journal, mais chaque fois que j'essayais d'accéder aux propriétés, cela me donnait une erreur non définie.

Code API:

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

auparavant je revenais juste:

return Json(string Of object);

0

J'ai eu un problème similaire aujourd'hui dans React. Finalement réalisé que le problème était dû au fait que l'état n'était pas encore défini. J'appelais user.user.nameet bien qu'il apparaisse dans la console, je n'arrivais pas à y accéder dans mon composant jusqu'à ce que j'inclue une vérification pour vérifier s'il user.userétait défini, puis que j'appelais user.user.name.

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.