2017-07-09 1 views
1

so versuche ich zweimal meinen SWAPI JSON-Server mit der Homeworld-ID zu holen, um den Heimatworternamen zu bekommen, aber ich bekomme nur "TypeError: Kann Eigenschaft 'name' von undefined nicht lesen". Ich bin ziemlich neu zu Reagieren, wenn es chaotisch aussieht tut mir leid! Danke im Voraus!Reag Multiple Fetch aus Zustand

import React, { Component } from 'react'; 
import './Card.css'; 

const person = personID => 
`http://localhost:3008/people/${personID}` 

const picture = pictureID => 
`http://localhost:3008/${pictureID}` 

// const planet = planetID => 
// `http://localhost:3008/planets/${planetID}` 

class Card extends Component { 
    constructor(props){ 
    super(props); 
    this.state ={ 
     requestFailed: false, 
     person: 1, 
     planet: 4 
    } 
    } 
    componentDidMount(){ 
    fetch(person(this.state.person)) 
    .then(response => { 
     if(!response.ok) { 
     throw Error("Network Request Failed"); 
     } 
     return response 
    }) 
     .then(d => d.json()) 
     .then(d => { 
     this.setState({ 
      cardData: d 
     }) 
     },() => { 
     this.setState({ 
      requestFailed: true 
     }) 
     }) 

fetch(`http://localhost:3008/planets/${this.state.cardData.homeworld}`) 
     .then(data => data.json()) 
     .then(data => { 
     this.setState({ 
      homeData: data 
     }) 
     }) 
    } 

    render() { 
    if(this.state.requestFailed === true) return <p>Error please try 
again!</p> 
    if(!this.state.cardData) return <p>Loading ...</p> 
    return (
     <div className='card'> 
     <div className='card-content'> 
      <div className='card-name'>{this.state.cardData.name}</div> 
      <img src={picture(this.state.cardData.image)} 
alt='profile'/> 
      <p> 
      <span>Birthday:</span> 
      <span>{this.state.cardData.birth_year}</span> 
     </p> 
     <p> 
      {/* Note that in order to get the homeworld's name, you have to get the planet name from a different endpoint than the people */} 
      <span>Homeworld:</span> 
      <span>{this.state.homeData.name}</span> 
     </p> 
    </div> 
    </div> 

    ); 
    } 
} 


export default Card; 

Antwort

1

Es ist wie das erste Problem sieht, ist, dass Sie versuchen, homeData.name zu machen, bevor es geladen wird. Sie sollten wahrscheinlich eine Ladeprüfung ähnlich der cardData Ladeprüfung haben. Oder Sie könnten einfach nichts machen, bis es geladen wird:

{this.state.homeData ? 
    <span>{this.state.homeData.name}</span> : 
    <span>Loading...</span> 
} 

Das zweite Problem ist, dass Sie die zweite fetch von homeData zur gleichen Zeit wie die erste fetch tun. Also diese Zeile:

fetch(`http://localhost:3008/planets/${this.state.cardData.homeworld}`) 

Wird immer scheitern, weil die cardData nicht in den Zustand noch geladen wird, wenn es läuft.

Was Sie tun sollten, ist es in der Antwort ein Teil der ersten Anfrage bewegen:

fetch(person(this.state.person)) 
    .then(response => { 
    if(!response.ok) { 
     throw Error("Network Request Failed"); 
    } 
    return response 
    }) 
    .then(d => d.json()) 
    .then(d => { 
    this.setState({ 
     cardData: d 
    }) 

    fetch(`http://localhost:3008/planets/${d.homeworld}`) 
     .then(data => data.json()) 
     .then(data => { 
     this.setState({ 
      homeData: data 
     }) 
     }) 
    },() => { 
    this.setState({ 
     requestFailed: true 
    }) 
    }) 

Es würde diese in separate Funktionen extrahieren helfen sie ein wenig aufzuräumen.