0
votes

I have a React module that makes a call to a function from an API in another JS module it imports. This function makes an async call to a flask route in my backend which returns a JSON object.

setSearchData is a useState.

In my React app, I setSearchData(getData(searchTerm)) with the expectation that the getData(searchTerm) function will asynchronously return something. When my promsie is resolved it should pipe jason data as such:

flask route -> searchAPI async func -> exported API func -> setState via hook

getsearch(search_term) -> flaskRoute(route, searchTerm) -> getSearchData(searchTerm) -> setSearchData( getSearchData(searchTerm) )

This doesn't work of course. The JSON data does get returned but it never updates the state. It seems as if the state gets updated with null and doesn't wait for the promise to get resolved.

How can I get an async function to play nice with React state which is itself async?

api_flask_routes.py

from flask import jsonify, request

@bp.route('/search/<search_term>', methods=['GET'])
def getsearch(search_term):
    search_data = [
        ['stuff'],
        ['stuff'],
        ['stuff'],
        ...
    ]
    return jsonify(search_data)

SearchDataAPI.js

const flaskRoute = async (route, searchTerm="") => {
    try {
      const hostIPAddress = "http://127.0.0.1:5000";
      const endpoint = hostIPAddress + route + searchTerm;
      const configs = {
          method: "GET",
          mode: "cors",
          headers: {"Content-Type": "application/json"}
      }

      fetch(endpoint, configs)
        .then( res => res.json() )
        .then( json => { return json; } ) // I return json here!
    }
    catch (err) {
      console.log("flask route error", err);
    }
};

function getSearchData(searchTerm) {
   return flaskRoute("/api/search/", searchTerm); // returns json to importing module
}

MySearch.js this is a React component

import searchDataAPI from '../searchAPI/SearchDataAPI';

//// DATA RETRIEVAL FROM BACKEND ////
const [searchData, setSearchData] = useState(null);
const getSearchData = searchDataAPI.searchFunctions.getSearchData;

function handleSubmitSearch(e) {
  e.preventDefault();
  if (searchTerm.trim().length > 0) {
      setSearchData(null); // clears out previous search data
      setSearchData(getSearchData(searchTerm)); // this doesn't work!
      // more stuff...
    }
}

1

1 Answers

0
votes

you have to wait for your function resolve by using .then() like the following :

 getSearchData(searchTerm).then(result => {
    setSearchData(result)
});

if it still return null, then you have to change your getSearchData() to async, so it can also return the resolve result like :

async function getSearchData(searchTerm) {
   return await flaskRoute("/api/search/", searchTerm).then(res => {
    return res;
  });
}

if that also doesn't work, you can directly setState inside getSearchData() like :

function getSearchData(searchTerm) {
   flaskRoute("/api/search/", searchTerm).then(result => {
     setSearchData(result);
});
}