为什么我的函数不向App Display返回任何内容?

时间:2020-09-18 09:03:39

标签: api flutter asynchronous dart

我正在尝试创建我的第一个小API项目,该项目中,斯蒂芬·金的所有书评和书名都应通过纽约时报api在屏幕上显示。

我试图创建一个Future并将卡返回到App Display,但什么都没有显示。在打印结果时效果很好。但是我在屏幕上看不到任何东西。我只想要一张显示所有结果的卡,就像在控制台中一样。 (至少目前)

我向您展示了完整的代码:

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: BookReview(),
    );
  }
}

//outsource the class BookReview for OOP
class BookReview extends StatelessWidget {
  List<int> bookNum = [
    0,
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    11,
    12,
    13,
    14,
    15,
    16,
    17,
    18,
    19,
    20,
    21,
    22,
    23,
    24,
    25,
    26,
    27,
    28,
    29,
    30,
    31,
    32,
    33,
    34,
    35,
    36,
    37,
    38,
    39,
    40,
    41,
    42,
    43,
    44,
    45,
    46,
    47,
    48,
    49,
    50,
    51,
    52,
    53,
    54,
    55,
    56,
    57,
    58,
    59,
    60,
    61,
    62,
    63,
    64,
    65
  ];

  static const apiKey = 'jH8F2A1FCudwGV8udVAU4YSLLEr8vqxT';
  static const apiURL =
      'https://api.nytimes.com/svc/books/v3/reviews.json?author=Stephen+King&api-key=$apiKey';

  Future<Card> getBookData() async {
    String bookTitle;
    String reviewURL;

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

    if (response.statusCode == 200) {
      var decodedData = jsonDecode(response.body);

      //TODO make an array with the number of results and save the value into a variable
      //highest array number is 65 so there are 66 results at the end
      for (int book in bookNum) {
        String bookTitle = decodedData['results'][book]['book_title'];
        String reviewURL = decodedData['results'][book]['url'];

        print(bookTitle + ' ' + reviewURL);
      }
      return Card(
          color: Colors.red,
          child: Column(
            children: [Text(bookTitle + reviewURL)],
          ));
    } else {
      print(response.statusCode);
      throw ('there is an error with the status code');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Stephen King NYT Reviews'),
      ),
      body: Column(
        children: [
          FlatButton(
            onPressed: () {
              getBookData();
            },
            child: Icon(
              Icons.picture_as_pdf,
              size: 50.0,
            ),
          ),
        ],
      ),
    );
  }
}
```

2 个答案:

答案 0 :(得分:0)

您的窗口小部件BookReview 是无状态的,因此在第一次创建时...以后不会更改...

现在您有两种方法...。

首先将您的小部件更改为stateFull并在获取日期后调用SetState()...

第二种方式仍然使用无状态小部件并使用Future Builder ... https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html


第一种方法示例 https://dartpad.dev/7de589d386edba57472efba02e90c4c3 此代码在dartpad上不起作用,因为使用了http库。请将其复制到您的项目中。

与此网站一起创建的类MyResponses ... https://javiercbk.github.io/json_to_dart/

答案 1 :(得分:0)

我改为有状态,也改为setState,但是什么也没发生。没有卡出现。


import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: BookReview(),
    );
  }
}

//outsource the class BookReview for OOP
class BookReview extends StatefulWidget {
  static const apiKey = 'jH8F2A1FCudwGV8udVAU4YSLLEr8vqxT';
  static const apiURL =
      'https://api.nytimes.com/svc/books/v3/reviews.json?author=Stephen+King&api-key=$apiKey';

  @override
  _BookReviewState createState() => _BookReviewState();
}

class _BookReviewState extends State<BookReview> {
  Card bookCard;

  var bookNum = List.generate(66, (i) => i);

  Future<Card> getBookData() async {
    String bookTitle;
    String reviewURL;

    http.Response response = await http.get(BookReview.apiURL);

    if (response.statusCode == 200) {
      var decodedData = jsonDecode(response.body);

      //TODO make an array with the number of results and save the value into a variable
      //highest array number is 65 so there are 66 results at the end
      for (int book in bookNum) {
        String bookTitle = decodedData['results'][book]['book_title'];
        String reviewURL = decodedData['results'][book]['url'];
      }
      print(bookTitle);
      print(reviewURL);

      return Card(
          color: Colors.red,
          child: Column(
            children: [Text(bookTitle + reviewURL)],
          ));
    } else {
      print(response.statusCode);
      throw ('there is an error with the status code');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Stephen King NYT Reviews'),
      ),
      body: Column(
        children: [
          FlatButton(
            onPressed: () async {
              final Card tmpBookCard = await getBookData();
              setState(() {
                bookCard = tmpBookCard;
              });
            },
            child: Icon(
              Icons.picture_as_pdf,
              size: 50.0,
            ),
          ),
        ],
      ),
    );
  }
}