Returning a promise object instead during retrieval

I have a mapping and in each mapping i want to get data in the file storage IPFS such as the name. Then I want to return the name on the interface. However, I get a “Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.” Can someone please help me? been trying to solve this for hours. Can’t seem to understand why because I know that hName should be a string.

{this.props.hawkers.map((hawker, key) => {
          const hawkerDetails = axios
            .get("https://ipfs.infura.io/ipfs/" + hawker.profileHash)
            .then(function (response) {
              console.log("this is the data: ", response.data);
              return response.data;
            })
            .catch(function (error) {
              console.log(error);
            });

          const hName = hawkerDetails.then((details) => {
            return hName;
          });
 return (
            <>
              <h4 style={{ display: "flex", marginTop: 20 }}>
                <Link
                  to={`/hawkerInfo/${hawker.owner}`}
                  // state={{ chosenHawkerPk: hawker.owner }}
                  state={{ chosenHawkerPk: hawker }}
                >
                  {hName}
                </Link>
              </h4>

Answer

There are several things going on.

  1. You’re not using React state to manage your data.

  2. You’re passing in detailsas an argument to your then method, and then not using it so hName is meaningless. It should probably be details.hName.

  3. Ideally you want to create an array of promises and then process the data with Promise.all. In my example I’ve used async/await.

  4. Once you’ve set your state you then need to map over your data in your return to create the HTML.

// Initialise state
const [ hawkers, setHawkers ] = useState([]);

// Async function called by the `useEffect` method
async function getData() {

  // Create a list of Axios promises
  const promises = this.props.hawkers.map(hawker => {
    const url = `https://ipfs.infura.io/ipfs/${hawker.profileHash}`;
    return axios.get(url);
  });

  // Wait for all the data to return
  const responses = await Promise.all(promises);

  // Use `map` to return a new array of each response's data
  const hawkers = data.map(response => response.data);

  // Set the state with that array
  setNames(hawkers);
}

// useEffect runs once if you pass in an empty
// array dependency
useEffect(() {
  getData();
}, []);

if (!hawkers.length) return <div>Loading</div>;

// Now just `map` over the data that you put in state
return (
  <>
    {hawkers.map(hawker => {
      <h4>
        <Link to={`/hawkerInfo/${hawker.details.owner}`}>
          {hawker.details.name}
        </Link>
      </h4>
    })};
  </>
)