2
votes

Un tableau avec des objets, dans un objet n'est pas défini

J'ai un tableau qui contient des objets, à l'intérieur d'un objet. Je peux console.log le premier objet et le tableau, mais lorsque j'essaie d'accéder aux objets dans le tableau ou d'utiliser la fonction de carte sur le tableau, j'obtiens une erreur qui dit "Impossible de lire la propriété d'undefined".

J'ai effectué une recherche approfondie sur SO et d'autres sites pour des problèmes similaires et j'en ai trouvé quelques-uns mais aucune réponse ne semble fonctionner pour moi.

L'objet ressemble à ceci:

render() {
return (
  <div className="main-content">
    <h2>{this.state.data.text} </h2>
    {console.log(this.state.data.answers[0].text)}
    <p>Introducing <strong>{this.state.id}</strong>, a teacher who loves teaching courses about <strong>{this.state.id}</strong>!</p>
    <input
    type="text"
    onChange={e => this.setState({ message: e.target.value })}>
    </input>
    <button onClick={() => {this.handleAnswerPost(this.state.message)}}>Answer</button>
  </div>
    );
  }
}

Et je peux y accéder en utilisant: this.state.data

Je veux accéder aux objets à l'intérieur du tableau de réponses comme:

getQuestionFromDb = () => {
    axios.get(`http://localhost:3000/questions/${this.state.id}`)
    .then(res => this.setState({
      data: res.data
    }));
  };


4 commentaires

pouvez-vous fournir l'objet exact


Pouvez-vous s'il vous plaît poster un exemple de code complet


Pouvez-vous publier plus de code? Au moins le code qui déclenche réellement l'erreur.


Plus de code nécessaire. Veuillez également indiquer comment cet objet a été créé et si des opérations asynchrones sont exécutées pour modifier cet objet


4 Réponses :


0
votes

La raison pour laquelle nous ne pouvons pas accéder à la clé d'objet en Javascript, c'est généralement parce que la variable / valeur n'est pas du type Object. Veuillez vous assurer que le type this.state.data est Object. Vous pouvez essayer console.log (typeof this.state.data) . Nous devrions nous attendre à ce qu'il soit en sortie object . Si le type est string , vous devez d'abord l'analyser avec JSON.parse () .


6 commentaires

Qui imprime objet


Et si vous essayez console.log (Object.keys ((this.state.data)) ? Quelle est la sortie ?. Nous devrions nous attendre à ["answer", "createdAt", .. .] .


Oui, la sortie attendue est imprimée dans la console.


Je n'ai aucune idée si la clé "réponse" existe mais renvoie l'erreur undefined lors de l'accès. Vous devriez peut-être reconstruire une partie de votre code en codesandbox.io ou jsbin.com. Pour que les gens puissent mieux vous aider.


Ou vous pouvez effectuer une vérification conditionnelle avant d'y accéder en this.state.data.answers && this.state.data.answers.length && console.log (this.state.data.answers [0])


Lisez simplement votre mise à jour, il semble que les données ne soient pas encore vraiment disponibles lors de la phase de rendu. Je suppose que vous avez obtenu la sortie attendue du code que je suggère après avoir précédemment montré `` non défini ''.



0
votes

Plusieurs raisons peuvent empêcher l'affichage de l'objet de données:

  • L'objet n'était pas en état au moment de son appel. Cela peut être dû au fait qu'un opérateur asynchrone ne charge pas les données. Par exemple. si vous demandez l'objet à partir de la base de données, il y a de fortes chances qu'au moment de passer un appel pour récupérer les données ( this.state.data ), la réponse n'avait pas été donnée.

  • L'objet n'a peut-être pas été analysé en chaîne. Essayez d'exécuter console.log (typeof this.state.data) . Si la sortie est string , vous devrez peut-être l'analyser. Si la sortie est indéfinie , alors le premier point est valide


0 commentaires

1
votes

Cela peut ne pas fonctionner lorsque les données ne contiennent pas de réponses [] lors du tout premier montage d'un composant.

Vous pouvez vérifier l'existence de votre tableau comme suit:

< pré> XXX


1 commentaires

le problème est que votre état initial ne contient pas data.answers . ce n'est qu'une façon de le résoudre.



3
votes

componentDidMount est appelé lorsque votre composant fait partie du DOM, mais l'appel que vous faites pour remplir votre état est asynchrone en raison de XHR, ce qui peut prendre 100 à 300 ms de plus pour obtenir les données dans votre composant, donc this.state.data.answers ne sera pas disponible dans le cycle initial de render () .

puisque vous avez mentionné l'utilisation d'une boucle, je suggère de définir une forme d'état initial comme

return this.state.data.answers.length ? loopItemsHere : <div>Loading..</div>

votre rendu initial n'aura rien à boucler mais dès qu'il résoudra les données et définira le nouvel état, il sera rendu correctement.

vous pouvez aussi

this.state = { 
  data: { 
    answers: [] 
  } 
}

évidemment, loopItemsHere peut être tout ce que vous écrivez pour afficher les réponses.


1 commentaires

Merci, cela a vraiment aidé! Mais comment se fait-il que je puisse accéder aux parties «externes» de l'objet et non au tableau imbriqué des «réponses»?