Enguias
Enguias

Reputation: 73

How to make an axios expression await until it receives a response

So I have a React App that comunicates with my API that returns JSON data, and I want to parse that data to my results array. The problem is that axios is async, so when I execute my function, results array will be returned before it gets parsed the data from the response, and it will log as empty, so I can't use my response array in the rest of the project. How do I make the axios expression in my function to wait until it has a response and then execute the rest?

Function:

async function pin(){

  const result = []
  var url = "my_api_url"

  axios.get(url)
  .then((res)=>{
    if(res.data){
          result = JSON.parse(res.data.data)
    }
  })
  console.log(result);
  return result;
}

This is the react right after the function:

export default function App(){

  const{isLoaded, loadError} = useLoadScript({
    googleMapsApiKey: "my_api_key",
    libraries,
  })

  const [markers, setMarkers] = React.useState([]);
  if(loadError) return "Erro a carregar o mapa"
  if(!isLoaded) return "Carregando"

  const result = []

  return <div>
    {pin()}
    <GoogleMap 
    mapContainerStyle={mapContainerStyle} 
    zoom={11} 
    center={center}
    >
    </GoogleMap>
  </div>
}

I'm just calling the function here to see if it's OK, I haven't implemented it yet. I have already tried to switch .then to .await but I get the error Objects are not valid as a React child (found: [object Promise])

Upvotes: 0

Views: 6340

Answers (2)

Nikki9696
Nikki9696

Reputation: 6348

Okay, so this has been a fun learning experience for me, as I am also new to React.

This sample worked for me. I don't have an example where it's an array but you see how I had to use the state to track things and make it show up as a json string so it would render. I assume you want the pin function outside the component for some reason so I passed in the state handler.

Hopefully this helps you out.

import * as React from 'react';
import './App.css';
import axios from 'axios';


const pin = async (handler) => {
  let result = []
  var url = "https://jsonplaceholder.typicode.com/todos/1"
  const res = await axios.get(url);
  result[1] = JSON.stringify(res.data);
  handler(result);
}

function App() {
   const [results, setResults] = React.useState('');

  React.useEffect(() => {
    if (!results) {
        pin(setResults);
    }
  },[results]);

  return (
    <div>
      <h1>some header</h1>
      <div>{results}</div>
    </div>
  );
}

export default App;

Upvotes: 2

mattyp1007
mattyp1007

Reputation: 11

You can return the promise in your pin function like so:

async function pin(){

  const result = []
  var url = "my_api_url"

  return axios.get(url)
}

Then wherever you are calling the pin function, you can chain your .then. Example:

pin()
  .then((res)=>{
    // do something with the data
  })

Upvotes: 1

Related Questions