Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
76 views
in Technique[技术] by (71.8m points)

javascript - Dynamically return Values from Axios-Request within function

How do I wait and/or build a return with values that come from an API-Call via axios in react?

The problem im Facing is that axios requests are asynchronous. Thats why the return from my code is hit earlier then the response from my request arrives. I'm trying to build Cards from a Weather API (openweathermap) that are returned when you enter certain parameters.

Here is how far I got. Hope you can help me:

function WeatherTile() {

 let data;

const options = {
  method: 'GET',
  url: 'https://api.openweathermap.org/data/2.5/weather',
  params: {
    appid: WEATHER_API_KEY,
    id: '2924585',
    lang: 'null',
    units: '"metric" or "imperial"',
    mode: 'xml, html'
  }
};

axios.request(options).then(function(response) {
    if(response.status == 200){
      mobxInteractionStore.setWeatherdata(response.data); // mobx doesnt work either. Its empty when the html is returned.
      console.log("SUCCESS");
      console.log(response.data);
      data = response.data; // This does not work
    }else {
      console.log(response.status);
    }
  }).catch(function(error) {
    console.error(error);
  });

return (
    <Card style={{ width: '18rem' }}>
      <Card.Img variant="top" src="holder.js/100px180" />
      <Card.Body>
        <Card.Title>{data.weather.description}</Card.Title>
        <Card.Text>
          Some quick example text to build on the card title and make up the bulk of
          the card's content.
        </Card.Text>
        <Button variant="primary">Go somewhere</Button>
      </Card.Body>
    </Card>
);
}

export default (WeatherTile);
question from:https://stackoverflow.com/questions/65944142/dynamically-return-values-from-axios-request-within-function

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For this use case I suggest just creating some local state representing the data you receive from the weather api. Based on this state you can then conditionally render the card body (The part of the jsx that requires to have the weather api data).

So that could look something like this:

import { useState, useEffect } from "react";

function WeatherTile() {
  const [data, setData] = useState(null);

  const options = {
    method: "GET",
    url: "https://api.openweathermap.org/data/2.5/weather",
    params: {
      appid: WEATHER_API_KEY,
      id: "2924585",
      lang: "null",
      units: '"metric" or "imperial"',
      mode: "xml, html",
    },
  };

  useEffect(() => {
    axios
      .request(options)
      .then(function (response) {
        if (response.status == 200) {
          setData(response.data);
        } else {
          console.log(response.status);
        }
      })
      .catch(function (error) {
        console.error(error);
      });
  }, []);

  return (
    <Card style={{ width: "18rem" }}>
      <Card.Img variant="top" src="holder.js/100px180" />
      {data && (
        <Card.Body>
          <Card.Title>{data.weather[0].description}</Card.Title>
          <Card.Text>
            Some quick example text to build on the card title and make up the
            bulk of the card's content.
          </Card.Text>
          <Button variant="primary">Go somewhere</Button>
        </Card.Body>
      )}
    </Card>
  );
}

The useEffect hook is used to start the axios request once after mount. If the request was successful we update the state with the data from the api. This triggers a rerender, data is defined so the card body is shown.

Conditional rendering in this example uses short-circuit evaluation, see this article for some more explanation and conditional rendering techniques in general.


Also when I tried this request out, data.weather was an array. So if you want to show the description of the first element in this array you need to do this:

data.weather[0].description

instead of this:

data.weather.description

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...