0

I am new to React and I am creating a website where the user can search for a query and the results are shown.

I have one component called: Searchbar which contains two functions:

1) postQuery() The user writes a query, which is sent via axios POST request to the backend when the user presses enter.

2) getQueryResult() The backend searches the relative query and sends the results back via axios GET request.

Therefore the order is: postQuery()-->getQueryResult() so I think that postQuery() creates a promise that, if resolved, allows getQueryResult() to run. However when the user clicks enter the first time, the results variable does not get updated. Only when he clicks enter the second, third etc. time the setResult updates the results. Therefore I think that my Promise of postQuery() is not executed first.

This is what I get in console:

Console

The first time, when enter is pressed for the first time, the results does not get updated. But the second time yes.

Searchbar code

function Searchbar() {

  const [query, setQuery] = useState("");
  const [results, setResults] = useState(["myemptyinitiallist"]);

  function postQuery(query) {
    console.log(query)
    var myParams = {
      data: query
    }

    return axios.post('http://localhost:5000/api/query', myParams)
      .then(function(response){
        // console.log("Yes, it sends the query in JSON format to Flask");
      })
      .catch(function(error){
        console.log(error, "Error on AXIOS post");
        throw error; // don't fulfill returned promise
      });
  } // End of function:  postQuery()

  function getQueryResult() {
    axios.get('http://localhost:5000/api/query')
      .then(function (response) {
        setResults(response.data); //set the value
        // console.log(response.data["my_results"])
        // console.log(results)
      })
  } // End of function: getQueryResult()

    function handleEnter(query){
        if (query != "") {
      postQuery(query).then(() => getQueryResult());
      console.log(results)
    } else {
        alert("The search query cannot be empty")
      }
  } // End of function: handleEnter()



    return(
    <div>
        <SearchBar
            onChange={(event) => setQuery(event)}
            onRequestSearch={() => handleEnter(query)}
            style={{
                marginTop: 200,
                marginLeft: 'auto',
                marginRight: 'auto',
                maxWidth: 800,
            }}
        />
     <ResultList/>
</div>
    )
}
Prova12
  • 643
  • 1
  • 7
  • 25
  • Your `getQueryResult` doesn't return a promise. Do that instead of calling `setResults`. Then wait for the promise result in your `handleEnter` function - do not immediately `console.log(results)` before they will become available in the future. – Bergi Oct 13 '19 at 15:54
  • I am not sure if I understand correctly. Why do I need a Promise for `getQuesryResult`? I thought the following: `postQuery` executes-->It returns a Promise-->If the promise is valid-->`setQueryResult` executes--> It sets the new value of `results` via `setResults` – Prova12 Oct 13 '19 at 15:58
  • Yes, that's what it currently does. But your `handleEnter` function tries to log the `results` before they are set, and returning a promise from `getQueryResult` is the proper solution to allow `handleEnter` to wait for them - just like you made the `getQueryResult()` call wait for the `postQuery()` promise. – Bergi Oct 13 '19 at 16:01
  • I tried also: `postQuery(query).then(() => getQueryResult().then((fetched_results)=>setResults(fetched_results)));` but same problem – Prova12 Oct 13 '19 at 16:25
  • That should work. But you will need to omit the `console.log(results)`, and instead put a `console.log(fetched_results)` in that callback as well. – Bergi Oct 13 '19 at 17:21
  • So you are sating that it should work but since my `console.log(results)` is outside the callback function, it will be executed first that is why on the first "enter clicking" the results are not updated? – Prova12 Oct 13 '19 at 17:29
  • I get the error `'fetched_results' is not defined` but doing: `postQuery(query) .then(() => getQueryResult() .then( (fetched_results)=>setResults(fetched_results), console.log(fetched_results) ) )` – Prova12 Oct 13 '19 at 17:38
  • 1
    I think you can do the following: `function getQueryResult() { return axios.get('http://localhost:5000/api/query') .then(function (response) { setResults(response.data); }) }` and `function handleEnter(query){ if (query != "") { postQuery(query) .then(() => getQueryResult() ); } else { alert("The search query cannot be empty") }`. You do not see the results updated because `console.log(results)` it is executed before the `.then()` – Magofoco Oct 13 '19 at 18:04
  • @Prova12 Don't use an arrow shorthand, and don't use comma operators. In this case, it wasn't even a comma operator, but a comma that separates the arguments of the `then` call. Instead, use `.then(fetched_results => { setResults(fetched_results); console.log(fetched_results); })` – Bergi Oct 13 '19 at 18:08

0 Answers0