web-dev-qa-db-fra.com

Impossible d'accéder à la propriété d'objet, même si elle existe. Renvoie undefined

Cela me déconcerte. Je ne sais pas comment l'expliquer autrement, mais voici à quoi ressemble mon code de débogage. En dessous, vous pouvez voir la sortie de ces deux journaux. La première montre clairement l'objet JavaScript complet avec la propriété à laquelle j'essaie d'accéder, mais le code de ligne suivant auquel je ne peux pas accéder avec config.col_id_3 (voir "indéfini" dans la capture d'écran?). Quelqu'un peut-il expliquer cela? Je peux également accéder à toutes les autres propriétés, à l'exception de field_id_4.

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

C’est ce que ces console.log () s impriment dans la console

Console output

242
Brian Litzinger

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. C'est pas l'état de l'objet lorsque vous console.log 'l'objet.

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 trouverez (généralement) que les clés sont ajoutées après votre appel console.log.

234
Matt

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

Lors de l'exécution de console.log() sur tout l'objet, tous les champs de document (tels que stockés dans la base de données) s'afficheraient. Cependant, certains utilisateurs ayant accès à une propriété renverraient undefined, alors que d'autres (y compris _id) fonctionneraient correctement.

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

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

36
ramin

Vérifiez si à l'intérieur de l'objet existe 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é 'name' à partir de 'category' et j'ai l'erreur undefined error, 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 contenait un tableau d'objets à l'intérieur de la clé de catégorie, car il pouvait avoir plusieurs objets de catégorie. Donc, pour obtenir la clé 'name', j'ai utilisé ceci:

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

Et ça fait l'affaire.

C'est peut-être trop tard pour cette réponse, mais j'espère que quelqu'un qui a le même problème trouvera cela comme je le faisais avant de trouver la solution :)

21
Asaf Lopez

La propriété que vous essayez d'accéder peut ne pas exister 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);
18
Lai Xue

J'ai eu le même problème. La solution pour moi consistait à utiliser la sortie stringifiée comme entrée pour analyser le JSON. cela a fonctionné pour moi. espérons que cela vous sera utile

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

Dans mon cas, je transmettais un objet à une promesse, j'y ajoutais plus de clés/de valeurs et, lorsque cela était fait, la promesse renvoyait l'objet.

Cependant, un léger sur-examen de ma part, la promesse renvoyait 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, je voyais l'objet complètement mis à jour mais je ne pouvais pas accéder aux clés - elles revenaient indéfinies. Jusqu'à ce que j'ai vu 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. Lorsque je la survolai, il indiquait Object value at left was snapshotted when logged, value below was evaluated just now. C’est alors que j’ai pensé que mon objet était en cours d’évaluation avant que la promesse ne l’ait complètement mise à jour.

9
rolinger

J'ai eu du mal à résoudre ce problème aujourd'hui et je pensais laisser une réponse avec ma solution.

Je cherchais un objet de données via ajax, à peu près comme ceci: {"constants": {"value1":"x","value2":"y"},"i18n" {"data1":"x", "data2":"y"}}

Disons que cet objet est dans une variable appelée data. Chaque fois que j'ai référencé data.i18n, j'ai eu undefined.

  1. console.log(data) a montré l'objet comme prévu
  2. console.log(Object.keys(data)) a dit ["constants","i18n"] comme prévu
  3. Renommer i18n to inter n'a rien changé
  4. J'ai même essayé de changer les données pour faire "i18n" le premier objet
  5. Déplacé le code pour s'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 révélait cela ... C'était un problème épineux ...

8
Jette

Mes données n'étaient que des chaînes 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, qu'il s'agisse d'une chaîne ou d'un objet.

Donc, pour que cela fonctionne, j'avais juste besoin de le reconvertir en objet réel:

object = JSON.parse(json_string_object);
6
makkasi

Je ne poste pas beaucoup ici à cause de l'irritation de ne pas avoir assez de posts pour commenter, mais le gars qui a posté ça en bas était correct. L'appel ajax n'était pas terminé lorsque vous avez tenté d'accéder à l'objet. Je voudrais même aller plus loin et utiliser 500 au lieu de 100 pour le délai d'attente, juste pour être sûr.

var a = config.col_id_3;    //undefined

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

}, 500);
4
almcaffee

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

J'ai eu un problème similaire, espérons que la solution suivante aide quelqu'un.
Vous pouvez utilisersetTimeoutfunction comme certains le suggèrent, mais vous ne savez jamais combien de temps exactement votre navigateur doit définir votre objet.

En dehors de cela, je suggérerais d'utilisersetIntervalfunction à la place. Il attendra que votre objet config.col_id_3 soit défini, puis déclenchera votre prochaine partie de code nécessitant des 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
Lefan
config = JSON.parse(config);

J'avais le même, les données étaient un texte et non un JSON comme je m'y attendais.

1
obotezat

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 remplacé find() en findOne() et tout a fonctionné pour moi.

Solution (si vous utilisez Mongoose): Assurez-vous de ne renvoyer qu'un seul objet pour pouvoir analyser son object.id ou il sera traité comme un tableau. Vous devrez donc y accéder comme ceci object[0].id.

1

Essayez avec config [0] ou config [0] .col_id_3

J'ai juste eu ce problème aussi, j'ai pu voir un objet, le connecter, mais pas y accéder à partir du code. J'ai alors essayé d'ajouter un [0] devant et j'ai résolu mon problème. Je pourrais alors accéder à toutes les propriétés.

1
Leonardo Atalla

J'ai eu le même problème et aucune solution ci-dessus n'a fonctionné pour moi et cela ressemblait à un travail de conjecture par la suite. Cependant, encapsuler mon code qui crée l'objet dans une fonction setTimeout 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
Tushar Shukla

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

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

Mon approche était la suivante ...

 creating my object... notice the white-space in "Word"

 response I get from my REST API

 javascript code to log the values

 log results from 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 ...

 result after removing whitespace

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

1
rey_coder

Dans mon cas, il se trouve que même si je reçois les données au format d’un modèle tel que myMethod(data:MyModelClass) object jusqu’à ce que l’objet reçu soit du type chaîne . content . La solution est juste d'analyser le JSON (dans mon cas) 

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

La pensée peut être utile.

1
Karthikeyan M

J'ai eu un problème comme celui-ci et j'ai trouvé que la solution était à 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 aussi les clés de l'objet:

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

> ["_wrapped","_chain"]

Cela m'a amené à réaliser que obj était en fait un wrapper Underscore.js autour d'un objet et que le débogage initial me mentait.

0
Marcus Downing

Excellentes suggestions. J'ai juste eu un problème similaire alors mes deux centimes ... Une chose qui a résolu le problème était l'ajout de "json: true" dans les options de ma requête. (Cela dépend bien sûr de la bibliothèque que vous utilisez, mais le principe général est le même: spécifiez le format de contenu que vous souhaitez recevoir.) 

0
itsKarma

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é, le problème a été résolu. Retrait de 

--mangle-props

de uglify-js était suffisant pour avoir du code uglified de travail. 

La meilleure pratique consiste peut-être à utiliser un préfixe pour les propriétés devant être modifiées avec la règle de regex 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 cela s'est passé:

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

J'ai rencontré le même problème aujourd'hui. Dans mon cas, les clés étaient imbriquées, c'est-à-dire key1.key2 . Je les ai divisées à l'aide de 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 je l'ai utilisé comme ceci, data [key1] [key2] qui a fait le travail pour moi.

0
C.O.G

Pour moi, cela s'est avéré être un problème lié au Mongoose.

Je parcourais des objets obtenus d'une requête Mongo. Je devais juste enlever:

await items = Model.find()

Et le remplacer par:

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

Excellentes suggestions ici. Je vais ajouter que quelqu'un peut le trouver utile. 

Soyez très conscient de la mise en cache, dans le navigateur ou à distance. 

Je me débattais avec cela alors que je développais en ligne et mettais en œuvre une stratégie simple.

  1. Je mets de l'anti-cache sur la charge du navigateur de mon script js . Quote: "ajoute une chaîne de requête"? V = 1 "à tous les fichiers .css et .js pour empêcher le cache
  2. Je mets un journal de console supplémentaire que je modifie avant d'essayer une nouvelle requête: .

Une fois la syntaxe correcte, j'ai supprimé le délai suggéré plus tôt, et tout va bien. Pour moi, je devais utiliser "JSON.stringify ("

0
Frieda

Juste au cas où cela serait utile pour quelqu'un, j'aurais un problème similaire, car 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 renvoyait "{" bar ":" Hello "," baz ":" World "}". Cependant, Object.keys (myObject) a révélé le "foo".

0
emote_control

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, mais cela se révélerait correct si j'écrivais l'objet entier à l'aide de console.log.

Il s'est avéré que le format CSV UTF-8 insérait 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-analyseur. La solution consistait à re-générer le CSV en utilisant l'option non-UTF, ce qui éliminait le caractère invisible.

0
Mike Rizzo

J'ai eu un problème similaire (lors du développement pour 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 dans fetch(), son appel asynchrone, je devais donc réécrire mon code 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);
    }
});
0
Mariyo

En 2018, Mozilla nous avertit dans le Mozilla Docs ici

Je cite "Consignation d'objets":

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 pour le moment vous vous enregistrez.

0
MTZ