0

I am fetching API data using axios and that API has query parameter (e.g.: searchQuery, which is defined in state). I have declared it's initial value in state and axios call in componentDidUpdate. Now I want my user to input the data in the form that on submit will change "seachQuery" in state. Here comes the problem, I want to display the initial results with the provided value and future results according to the user's input but it doesn't happen. Initial results did don't show up because componentDidUpdate will be called only after updating. And if I made axios call in componentDidMount, results according to the user input don't appear. I WANT TO DO IT USING CLASS BASED COMPONENTS ONLY.

  constructor(props) {
    super(props)
  
    this.state = {
      searchResult: [],
      formInput: "",
      searchQuery: "chicken",
    }
  }
componentDidUpdate(){
    axios.get(`https://api.edamam.com/search? 
       q=${this.state.searchQuery}&app_id=${this.state.APP_ID}&app_key=${this.state.APP_KEY}`)
            .then(res=>  
              this.setState(prevState =>({searchResult: prevState.searchResult.concat(res.data.hits)}))
              )
  }

onChangeHandler = (e) => {
    this.setState({
      formInput: e.target.value
    })
    console.log(e.target.value)



  }

  onSubmitHandler = (e) => {
    e.preventDefault()
    this.setState({
      searchQuery: this.state.formInput
    })
    // console.log(this.state.searchQuery)
    
    // setformInput("")
  }
  render() {
    return (
      <div className="App">
        <form className="search-form" onSubmit={this.onSubmitHandler}>
          <input className="search-bar" type="text" onChange={this.onChangeHandler} />
          <button className="search-button" type="submit">SEARCH</button>
        </form>
        <div className="recipes">
          {this.state.searchResult.map(singleRecipe => 
                          <Recipe key={singleRecipe.recipe.label} title={singleRecipe.recipe.label} calories={singleRecipe.recipe.calories} image={singleRecipe.recipe.image} ingredients={singleRecipe.recipe.ingredients}/>
          )}
        </div>
      </div>
    );
  }
}


export default App```
Umar Javed
  • 55
  • 8

2 Answers2

0

I think you can set the state(e.g. searchQuery) in componentDidMount.

componentDidMount() {
    this.setState({searchQuery: 'checken'});
}
First Arachne
  • 786
  • 1
  • 8
  • 18
0

Why are you setting formInput to user input and searchQuery to formInput onSubmit? Just set searchQuery to user input onChange.

onChangeHandler = (e) => {
  this.setState({
    searchQuery: e.target.value
  });
  console.log(e.target.value);
}

And fetch data in a function, use it on componentDidMount and onSubmit.

getData = () => {
  axios.get(`https://api.edamam.com/search? q=${this.state.searchQuery}&app_id=${this.state.APP_ID}&app_key=${this.state.APP_KEY}`)
    .then(res =>
      this.setState(prevState => ({ searchResult: prevState.searchResult.concat(res.data.hits) }))
    );
}

componentDidMount() {
  this.getData();
}

onSubmitHandler = (e) => {
  e.preventDefault();
  this.getData();
}
cuvan
  • 1
  • this will throw Axios request on every alphabet user enter, I only want to send axios request when user click the submit button. – Umar Javed Dec 25 '20 at 10:24
  • No, this is getting data onSubmitHandler which is triggered by this line;
    – cuvan Dec 25 '20 at 10:49