0

I want to pass values from SearchInput (parent) to FetchData (child) component. It does not work properly, because I have to click twice to fetch data and this.props.loaded should be true after click on submit button. I know, that I should use callback function, but I dont know, which function and where. I'm started to learn ReactJS a week ago.

import React, {Component} from "react";

import FetchData from "./FetchData";

export default class SearchInput extends Component {
  constructor(props) {
    super(props);
    this.state = {
      cityName: "",
      loaded: false
    }
    this.handleCityNameChange = this
      .handleCityNameChange
      .bind(this);
    this.handleSubmitButton = this
      .handleSubmitButton
      .bind(this);
  }
  handleCityNameChange = (e) => {
    const val = e.target.value;
    this.setState({cityName: val});
    e.preventDefault();
  }
  handleSubmitButton = (e) => {
    //const val = document.getElementById("search").value;
    this.setState({cityName: this.state.cityName, loaded: true});
    e.preventDefault();
  }
  render() {
    const {cityName, loaded} = this.state;
    return (
      <div>
        <form>
          <label htmlFor="search">Search city:</label>
          <input
            type="text"
            name="search"
            id="search"
            value={this.state.cityName}
            onChange={this.handleCityNameChange}/>
          <input type="submit" onClick={this.handleSubmitButton}/>
        </form>
        <FetchData
          cityName={cityName}
          loaded={loaded}
          handleSubmitButton={this.handleSubmitButton}/>
      </div>
    )
  }
}


import React, {Component} from "react";
import axios from "axios";

import DisplayWeather from "./DisplayWeather";

export default class FetchData extends Component {
    constructor(props) {
        super(props);
        this.state = {
            descriptionMain: "",
            description: "",
            temperature: null,
            weatherIcon: ""
        }
        
    }
    // otherFunc() {
    //     this.props.handleSubmitButton();
    //   }
    fetchData = () => {
        if (this.props.loaded) {
            const apiURL = `https://api.openweathermap.org/data/2.5/weather?q=${this.props.cityName}&units=metric&APPID=e6f4d816d3ade705ec1d8d9701b61e14`;
            console.log(apiURL)
            axios
                .get(apiURL)
                .then(res => {
                    this.setState({descriptionMain: res.data.weather[0].main, description: res.data.weather[0].description, temperature: res.data.main.temp, weatherIcon: res.data.weather[0].icon});
                })
        }
    }
    componentWillReceiveProps() {
        this.fetchData();
    }
    render() {
        return (
            <div>
                <DisplayWeather {...this.state} cityName={this.props.cityName}/>
            </div>
        )
    }
}


export default class DisplayWeather extends Component {
  render() {
    const {descriptionMain, description, temperature, weatherIcon, cityName} = this.props;
    return (
      <div>
        <h3>{cityName}</h3>
        <h4>Sky: {description}</h4>
        <h5>Description: {descriptionMain}</h5>
        <span className="temperature">{temperature}
          °C</span>
        <img
          src={`http://openweathermap.org/img/w/${weatherIcon}.png`}
          alt={`${description}`}/>
      </div>
    )
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Natalia
  • 1,009
  • 2
  • 11
  • 24

1 Answers1

0

You have to enclose the submit attribute in an arrow function:

onClick{()=>this.handleSubmutButton()}

Do the same for on change as well

akiespenc
  • 305
  • 3
  • 8
  • I changed SeachInput inputs to this and it does not work (cannot read property target of undefined - handleCityNameChange). ` this.handleCityNameChange()}/> this.handleSubmitButton()}/>` – Natalia Oct 05 '17 at 21:58
  • Pass your element into the parameters – akiespenc Oct 06 '17 at 00:00
  • It still does not work: for the first time I have to click two times to display data, when I type sth for the second time, I have error Uncaught (in promise) Error: Request failed with status code 404- probably because API was already loaded and handleCityNameChange was fired in onChange. ` this.handleCityNameChange(e)}/> this.handleSubmitButton(e)}/>` – Natalia Oct 06 '17 at 05:20