Проблема при получении данных из API во Flutter с помощью Dart - PullRequest
1 голос
/ 25 апреля 2020

У меня проблема с моим приложением, я создаю приложение для отслеживания цен на криптовалюту. Проблема в том, что я правильно получаю данные из API, затем печатаю их в адвокате, но когда я пытаюсь отобразить их в приложении, они отображают ноль.

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

class CurrencyData { var decodedData;
Future getCoinsData() async {

http.Response response =
    await http.get(coinUrl);

if (response.statusCode == 200) {
  decodedData = jsonDecode(response.body);
} else {
  print(response.statusCode);
  throw 'Problem with the request, try again later!';
}
return decodedData;
}
}

Вот код, по которому я вызываю данные для их отображения.

class _DashboardPageState extends State<DashboardPage> {
CurrencyData currencyData = CurrencyData();
  var btcPrice;
  var btcChange24h;
void cryptoCurrencyData() async {
    var data = await currencyData.getCoinsData();
print(btcPrice = data['data'][0]['priceUsd']);
print(btcChange24h = data['data'][0]['changePercent24Hr']);
}
@override
  void initState() {
super.initState();
cryptoCurrencyData();
}
  @override
  Widget build(BuildContext context) {
return Scaffold(
  body: SafeArea(
child: ListView(
  children: <Widget>[
Column(
  children: <Widget>[
        // the top bar
            Container(
              padding: EdgeInsets.all(40),
              constraints: BoxConstraints.expand(height: 175),
              decoration: BoxDecoration(
                color: Colors.lightBlue,
                boxShadow: [
                  BoxShadow(
                    color: Colors.black26,
                    blurRadius: 20.0,
                    // has the effect of softening the shadow
                    spreadRadius:
                        5.0, // has the effect of extending the shadow
                  ),
                ],
                borderRadius: BorderRadius.only(
                  bottomLeft: Radius.circular(30),
                  bottomRight: Radius.circular(30),
                ),
              ),
              child: Container(
                padding: EdgeInsets.only(top: 25),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Center(
                      child: Text(
                        'Crypto Tracker',
                        textAlign: TextAlign.center,
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 30.0,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    )
                  ],
                ),
              ),
            ),
            // the body part
            CurrencyWidget(
              currencyIconUrl: 'assets/images/btc.png',
              currencyName: 'Bitcoin',
              currencyShortName: 'BTC',
              currencyPrice: btcPrice,
              currencyChange24h: btcChange24h,
            ),

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

Изображение с нулевым значением

Скриншот данных, печатаемых в консоли

Есть идеи, что это за проблема?

1 Ответ

0 голосов
/ 25 апреля 2020

Проблема в том, что получение данных API является асинхронной c задачей, поэтому для этого требуется время, в то время как экран сборки метода сборки в это время выводит нулевое значение.

1) Вы можете вызвать setState в конце функции, которая заменяет ноль на фактические данные при получении из API.

void cryptoCurrencyData() async {
    var data = await currencyData.getCoinsData();
    btcPrice = data['data'][0]['priceUsd'];  // assign
    btcChange24h = data['data'][0]['changePercent24Hr']; // aasign
   print(btcPrice = data['data'][0]['priceUsd']);
   print(btcChange24h = data['data'][0]['changePercent24Hr']);
      setState(() {}); // added
   }

2) Однако FutureBuilder - более лучший вариант, где вы можете показать индикатор загрузки или что-то, что показывает данные загружается и отображается при поступлении.

Примечание: таким образом вам не нужен метод cryptoCurrencyData , а также вам не нужно хранить значение в другой переменной.

FutureBuilder(
        future: currencyData.getCoinsData(),
        builder: (_, sanpshot) {
          if (!sanpshot.hasData) {
            return CircularProgressIndicator();
          }
          return CurrencyWidget(
            currencyIconUrl: 'assets/images/btc.png',
            currencyName: 'Bitcoin',
            currencyShortName: 'BTC',
            currencyPrice: data['data'][0]['priceUsd'],
            currencyChange24h: data['data'][0]['changePercent24Hr'],
          );
        },
      ),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...