-1

I'm trying to create a program and my question is regarding a front-end and back-end React app, however I am having some trouble on the front end. Essentially, the user enters various cities and the names of the cities are stored in a city list. My issue is, the input isn't being updated. Meaning, the user can load the page and go to type their first city name into the input box and press the button I have implemented but nothing happens. The page doesn't refresh, the city isn't added to the list.. nothing happens. I do not know if the issue is with the button or my handleInputChange function or anything else. Any insight or guidance will be deeply appreciated.

I have tried a bunch of other solutions that I have found on SO, such as creating a dynamic key for the handleInputChange function or binding the handleInputChange to this (this.handleInputChange = this.handleInputChange.bind(this)), but nothing seems to be working.

constructor(props) {
    super(props);

    this.state = {
       weather: null,
       cityList: [],
       newCityName: ''
    };

    this.handleInputChange = this.handleInputChange.bind(this)
}

getCityList = () => {
    fetch('/api/cities')
    .then(res => res.json())
    .then(res => {
      var cityList = res.map(r => r.city_name);
      this.setState({ cityList });
    });
  };

  handleInputChange = (e) => {
    this.setState({ newCityName: e.target.value });
  };

  handleAddCity = () => {
    fetch('/api/cities', {
      method: 'post',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ city: this.state.newCityName })
    })
    .then(res => res.json())
    .then(res => {
      this.getCityList();
      this.setState({ newCityName: '' });
    });
  };

...

handleChangeCity = (e) => {
    this.getWeather(e.target.value);
  }

  componentDidMount () {
    this.getCityList();
  }

...

render() {
    return (
       <InputGroup>
         <Input 
             placeholder="New city name..."
             value={this.state.newCityName}
             onChange={this.handleInputChange}
          />
          <InputGroupAddon addonType="append">
             <Button color="primary" onClick={this.handleAddCity}>Add City</Button>
           </InputGroupAddon>  
        </InputGroup>
        <FormGroup>
          <Input type="select" onChange={this.handleChangeCity}>
            { this.state.cityList.length === 0 && <option>No cities added yet.</option> }
            { this.state.cityList.length > 0 && <option>Select a city.</option> }
            { this.state.cityList.map((city, i) => <option key={i}>{city}</option>) }
           </Input>
         </FormGroup>

I am not getting any error messages and everything is compiling. The main problem is nothing happens. I want the input to be taken and stored in the cityList and for the user to be able to input more cities. Again, any tips or advice is highly appreciated.

bdrige
  • 1
  • Change `value={this.state.newCityName}` to `defaultValue={this.state.newCityName}`! – Praveen Kumar Purushothaman Aug 21 '19 at 19:18
  • @PraveenKumarPurushothaman Unfortunately, the issue persists. Even after changing it to defaultValue, it is not giving any sort of response. – bdrige Aug 21 '19 at 19:29
  • First off (unrelated), add `this.function_name = this.function_name.bind(this)` for every function that uses `this.state` or `this.setState()` (except the ones from `React.Component` like `render()`) to avoid unexpected behavior. I think your problem lies in the fact that `handleInputChange` is an anonymous function, could you try rewriting it like this `function handleInputChange(e){...}` and see if that fixes the problem? – Taxel Aug 21 '19 at 19:47

1 Answers1

0

Try something like this:

<Input 
    placeholder="New city name..."
    value={this.state.newCityName}
    onChange={(e) => {this.handleInputChange(e)}}
/>

Reference: React: trigger onChange if input value is changing by state?

Tristan Heilman
  • 278
  • 1
  • 4
  • 16