【问题标题】:Flutter Sql FutureBuilder snapshot nullFlutter Sql FutureBuilder 快照 null
【发布时间】:2020-07-20 23:49:13
【问题描述】:

再次。对我来说,期货似乎是一个持续不断的困惑之源。

我正在尝试在页面上使用 FutureBuilder,但 snapshot.data 始终为空,即使我可以在 DBprovider 返回之前打印数据。

我有“CentreDetailScreen”类,它使用 initState 来创建未来。

class _CentreDetailScreenState extends State<CentreDetailScreen> {
  Future centreFuture;

  @override
  void initState() {
    super.initState();
    centreFuture = widget._centresBloc.getCentre(widget.centreReference);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder(
          future: centreFuture,
          builder: (context, snapshot) {
            switch (snapshot.connectionState) {
              case ConnectionState.none:
                return CircularProgressIndicator();
              case ConnectionState.active:
              case ConnectionState.waiting:
                return CircularProgressIndicator();
              case ConnectionState.done:
                print('snapshot: ${snapshot.data}'); <-always null
                return Container(...//build UI

在 CentresBloc 我有:

  Future<ClimbingCentre> getCentre(String centreId) async {
    print('BloC get Centre');  <-- this prints
    var _centre = await ClimbDB.db.getCentre(centreId);
    print('Bloc has got a centre $_centre') <-- this doesn't
    return _centre;
  }

然后 DBprovider ClimbDB 有:

Future<ClimbingCentre> getCentre(String centreId) async {
    try {
      var map = Map<String, dynamic>();
      map['action'] = _GET_ONE_ACTION;
      map['centreId'] = centreId;
      final response = await http.post(
          'http://xxx.xxx.xx.x/flutter/climbinside/centre.php',
          body: map);
      if (200 == response.statusCode) {
        var centre = json.decode(response.body);
        var toReturn =
            centre.map((centre) => new ClimbingCentre.fromJson(centre));
         print($toReturn); <-prints 'instance of ClimbingCentre'
        return toReturn;
      } else {
        throw Exception('we were not able to download json data');
      }
    } catch (e) {
      throw Exception('Get centre: unable to download JSON');
    }
  }

我已经尝试了很多不同的东西...有时我会收到关于 Future 不是 Future 的子类型的错误...其他导致“无法下载 JSON”异常触发...我想不通.

如果能提供任何帮助,我将不胜感激。

【问题讨论】:

  • 检查你的snapshot.error 里面是否有东西。未来可能会完成,但会出现错误而不是结果。
  • 试过print('snapshot error: ${snapshot.error}'); ?
  • @mFeinstein snapshot.error 给出 => 快照是例外:获取中心:无法下载 JSON... 我没有得到,因为 if(200) 位正在打印出响应。身体很好。
  • 您可能返回了不兼容的类型,因此异常在您的打印之后,因为您使用的是 var,所以可以肯定的是,打印异常 e 或调试变量。
  • 谢谢@mFeinstein。例外 e 是:“MappedListIterable”不是“FutureOr”类型的子类型...

标签: flutter future


【解决方案1】:

您应该始终检查snapshot 是否没有error

在您的情况下,您收到错误是因为您使用 var 定义了变量,这很棘手且容易出错,因为您没有得到编译器的全面帮助来让您知道您的代码将在运行时中断.始终尝试使用完全类型化的变量来避免这种陷阱,因此也要避免使用dynamic

您必须在存储库类中返回与您的Future&lt;T&gt; 相同类型的变量T

另外,尽量不要丢弃 Exception 变量,以某种方式将其传递给新的 Exception 对象(将其应用到 String 或理想情况下,将其作为内部 Exception 传递给构造函数),它包含调试您的有用信息代码。

【讨论】:

    【解决方案2】:

    已解决:

    它在 ClimbingCentre 的模型类中重写了 fromJson 方法后工作。我最初遵循flutter.dev的结构,如下所示:

      ClimbingCentre.fromJson(Map<String, dynamic> json) {
          centreId: json['CentreId'],
          name: json['Name'],
          imagePath: json['ImagePath'],
      }
    

    但是我改成这个了,我在别的课上用过的:

      factory ClimbingCentre.fromJson(Map<String, dynamic> jsonData) {
        ClimbingCentre c = ClimbingCentre(
          centreId: jsonData['CentreId'],
          name: jsonData['Name'],
          imagePath: jsonData['ImagePath'],
        );
        return c;
      }
    

    【讨论】:

      猜你喜欢
      • 2020-04-12
      • 2021-11-17
      • 2021-12-26
      • 1970-01-01
      • 2021-10-08
      • 2021-08-01
      • 1970-01-01
      • 2020-11-07
      • 2020-07-10
      相关资源
      最近更新 更多