Search code examples
reactjsfetchreact-componentreact-state

Can we send the JSON obtained from an API as a child component, instead of each individual attribute of the object?


I have been trying to send the data obtained by an API call to a child component via state and it doesn't seem to work.

I have been sending each individual attribute of the object as a prop to the child component.

Is there a way to send the whole JSON response as a prop to a child component?

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: {},
      name: ""
    };
  }
  componentWillMount() {
    this.getWeather();
  }
  getWeather(city) {
    fetch(
      `https://api.apixu.com/v1/current.json?key=2da827a3ce074ddb85417374xxxxxx&q=paris`
    )
      .then(res => res.json())
      .then(data => {
        this.getData(data);
      })
      .catch(err => {
        return Promise.reject();
      });
  }
  getData(data) {
    var location = data.location.name;

    this.setState({ data: data, name: location });
    console.log(this.state.name);
    console.log(this.state.data);
  }
  render() {
    return <Child name={this.state.name} data={this.state.data} />;
  }
}

class Child extends React.Component {
  render() {
    var data = this.props.data;
    return (
      <div>
        <h1>{this.props.name}</h1>
        <h1> {data.current.cloud}</h1>
      </div>
    );
  }
}

ReactDOM.render(<Parent />, document.getElementById("root"));

I expect the data object to also be passed to the child but it doesn't and I get a crash screen stating that the data object is undefined.

Is there a way to send the whole JSON obtained in an API call as a prop to a child component?


Solution

  • Your Child component will render before the getWeather api return the data. So this.props.data in Child component will be {}, app crash when you access data.current.cloud.

    You need to check whether data is not empty and it has current property. So your code should be

    class Child extends React.Component {
      render() {
        var data = this.props.data;
        return (
          <div>
            <h1>{this.props.name}</h1>
            <h1>{data && data.current ? data.current.cloud : ''}</h1>
          </div>
        );
      }
    }