Флаттер, получающий данные из API для метода сборки

#api #flutter #dart

#API #flutter #dart

Вопрос:

Я пытаюсь выполнить то, что, как мне казалось, было бы простым, прежде чем я начал изучать flutter.

 const apiKey = 'xxxxxx';
const coinApiURL = 'https://rest.coinapi.io/v1/exchangerate';

class _CurrencyState extends State<CurrencyScreen> {

void getData() async {
http.Response response = await http.get('$coinApiURL/BTC/USD?apikey=$apiKey');

String data = response.body;
double exchangeRate = jsonDecode(data)['rate'];
print(exchangeRate);
}

@override
  Widget build(BuildContext context) {
    getData(); // prints out the value
    print(exchangeRate); // error "Undefined name 'exchangeRate'"
    (...)
    child: Text($exchangeRate) // value has to be inserted here
  }
  

Поэтому, хотя я могу использовать функцию getData для печати содержащихся в ней данных, я не могу распечатать значение ‘ExchangeRate’. Поэтому я тоже не могу вставить значение в текстовый виджет.

Кто-нибудь может объяснить мне простыми словами, как это работает и как я могу получить значение переменной ‘ExchangeRate’ и использовать его в коде?

Комментарии:

1. flutter.dev/docs/cookbook/networking/fetch-data

2. На самом деле это не решает мою проблему, но я обновил свой вопрос, чтобы было легче понять, чего я пытаюсь достичь

3. вы не можете сделать это таким образом, у вас есть метод, Future исходящий из getData() , поэтому вы должны использовать FutureBuilder как в ссылке, которую я опубликовал

Ответ №1:

Я изменил ваш код, чтобы Text виджет создавался после getData завершения обработки данных ответа http.

 const apiKey = 'xxxxxx';
const coinApiURL = 'https://rest.coinapi.io/v1/exchangerate';

class _CurrencyState extends State<CurrencyScreen> {

// fetch http data and return rate value 
Future<double> getData() async {
http.Response response = await http.get('$coinApiURL/BTC/USD?apikey=$apiKey');
String data = response.body;
double exchangeRate = jsonDecode(data)['rate'];
print(exchangeRate);
// return exchangeRate value
return exchangeRate;
}

@override
  Widget build(BuildContext context) {
  return FutureBuilder<double>(
    // assign getData() to futureBuilder
    future: getData(),
    builder: (BuildContext  context, AsyncSnapshot<double> snapshot) {
      // handle getData error
      if (snapshot.hasError) {
        return Text('Error');
      }
      // handle success fetched data
      if (snapshot.hasData) {
        return Text(snapshot.data.toString());
      }
      // return progress indicator while loading data
      return Center(child: CircularProgressIndicator());
    },
     );
  }