【问题标题】:Flutter : Future Builder receive null from calssesFlutter:Futurebuilder 从类中接收 null
【发布时间】:2020-12-26 22:03:08
【问题描述】:

我正在尝试制作实时比分应用程序,我有一个由 quiqtype.io 从 json 创建的模型:

import 'dart:convert';

Live liveFromJson(String str) => Live.fromJson(json.decode(str));

String liveToJson(Live data) => json.encode(data.toJson());

class Live {
  Live({
    this.success,
    this.data,
  });

  bool success;
  Data data;

  factory Live.fromJson(Map<String, dynamic> json) => Live(
        success: json["success"],
        data: Data.fromJson(json["data"]),
      );

  Map<String, dynamic> toJson() => {
        "success": success,
        "data": data.toJson(),
      };
}

class Data {
  Data({
    this.fixtures,
    this.nextPage,
    this.prevPage,
  });

  List<Fixture> fixtures;
  String nextPage;
  bool prevPage;

  factory Data.fromJson(Map<String, dynamic> json) => Data(
        fixtures: List<Fixture>.from(
            json["fixtures"].map((x) => Fixture.fromJson(x))),
        nextPage: json["next_page"],
        prevPage: json["prev_page"],
      );

  Map<String, dynamic> toJson() => {
        "fixtures": List<dynamic>.from(fixtures.map((x) => x.toJson())),
        "next_page": nextPage,
        "prev_page": prevPage,
      };
}

class Fixture {
  Fixture({
    this.id,
    this.date,
    this.time,
    this.round,
    this.homeName,
    this.awayName,
    this.location,
    this.leagueId,
    this.competitionId,
    this.homeId,
    this.awayId,
    this.competition,
    this.league,
  });

  String id;
  DateTime date;
  String time;
  String round;
  String homeName;
  String awayName;
  String location;
  String leagueId;
  String competitionId;
  String homeId;
  String awayId;
  Competition competition;
  League league;

  factory Fixture.fromJson(Map<String, dynamic> json) => Fixture(
        id: json["id"],
        date: DateTime.parse(json["date"]),
        time: json["time"],
        round: json["round"],
        homeName: json["home_name"],
        awayName: json["away_name"],
        location: json["location"],
        leagueId: json["league_id"],
        competitionId: json["competition_id"],
        homeId: json["home_id"],
        awayId: json["away_id"],
        competition: Competition.fromJson(json["competition"]),
        league: json["league"] == null ? null : League.fromJson(json["league"]),
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "date":
            "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
        "time": time,
        "round": round,
        "home_name": homeName,
        "away_name": awayName,
        "location": location,
        "league_id": leagueId,
        "competition_id": competitionId,
        "home_id": homeId,
        "away_id": awayId,
        "competition": competition.toJson(),
        "league": league == null ? null : league.toJson(),
      };
}

class Competition {
  Competition({
    this.id,
    this.name,
  });

  String id;
  String name;

  factory Competition.fromJson(Map<String, dynamic> json) => Competition(
        id: json["id"],
        name: json["name"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
      };
}

class League {
  League({
    this.id,
    this.name,
    this.countryId,
  });

  String id;
  String name;
  String countryId;

  factory League.fromJson(Map<String, dynamic> json) => League(
        id: json["id"],
        name: json["name"],
        countryId: json["country_id"],
      );

  Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
        "country_id": countryId,
      };
}

我创建 API 服务类:

import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:myexpect/models/match_fixture.dart';

class Api {
  Future<Live> get_fixture() async {
    var fixture_model = null;
    var client = http.Client();
    try {
      var url =
          'https://livescore-api.com/api-client/fixtures/matches.json?key=xxxxxxC&secret=yyyyy&page=1';
      var response = await client.get(url);
      if (response.statusCode == 200) {
        var jsonString = response.body;
        var jsonMap = json.decode(jsonString);
        fixture_model = Live.fromJson(jsonMap);
        print(jsonMap ):                             //--- printed the list in console successfully 
      }
    } catch (Exception) {
      return fixture_model;
    }
  }
}

我现在正试图在此页面中查看这些数据在未来的构建中:

import 'package:flutter/material.dart';
import '../services/live_score_api.dart';
import '../models/match_fixture.dart';

class LiveScore extends StatefulWidget {
  @override
  _LiveScoreState createState() => _LiveScoreState();
}

class _LiveScoreState extends State<LiveScore> {
  Future<Live> _fixtures;

  @override
  void initState() {
    _fixtures = Api().get_fixture();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Live>(
      future: _fixtures,
      builder: (ctx, snapshot) {
        if (snapshot.connectionState == ConnectionState.none ||
            snapshot.connectionState == ConnectionState.waiting ||
            snapshot.connectionState == ConnectionState.active ||
            snapshot.data == null) {
          return Container(
            child: Text('Loading.......'),
          );
        } else {
          return ListView.builder(
              itemCount: snapshot.data.data.fixtures.length,
              itemBuilder: (ctx, index) {
                var data = snapshot.data.data.fixtures[index];
                return Text(data.time);
              });
        }
      },
    );
  }
}

当我加载这个页面时,数据列表在控制台打印成功,但未来的构建器收到 null,因此只查看文本“正在加载...”,没有错误没有发现异常

【问题讨论】:

    标签: api flutter dart


    【解决方案1】:

    您希望像这样实现您未来的构建器:

        return FutureBuilder<Live>(
          future: _fixtures,
          builder: (context, snapshot) {
           switch (snapshot.connectionState) {
              case ConnectionState.none:
              case ConnectionState.waiting:
              case ConnectionState.active:
                // Loading widget
                return CircularProgressIndicator();
              case ConnectionState.done:
                if (snapshot.hasError) {
                   // return error widget
                }
                if (snapshot.hasData) {
                 return ListView.builder(
                  itemCount: snapshot.data.data.fixtures.length,
                  itemBuilder: (ctx, index) {
                    var data = snapshot.data.data.fixtures[index];
                    return Text(data.time);
                  });
                }
            }
          },
        );
    

    最重要的是,您会捕获异常,但不会抛出异常。所以它不会抛出错误。这是您想在未来的建设者中了解的内容。我建议抛出异常。

    【讨论】:

    • 谢谢,它给了我错误:构建函数绝不能返回 null。要返回导致建筑小部件填满可用空间的空白空间,请返回“Container()”。要返回占用尽可能少空间的空白空间,请返回“Container(width: 0.0, height: 0.0)”。
    • 问题是snapshot.data = null,没有收到数据:(
    • 我从捕获异常中得到这个错误:另一个异常被抛出:构建函数返回 null。
    【解决方案2】:

    我发现了我的错误,在这里:

    import 'dart:convert';
    import 'package:http/http.dart' as http;
    import 'package:myexpect/models/match_fixture.dart';
    
    class Api {
      Future<Live> get_fixture() async {
        var fixture_model = null;
        var client = http.Client();
        try {
          var url =
              'https://livescore-api.com/api-client/fixtures/matches.json?key=xxxxxxC&secret=yyyyy&page=1';
          var response = await client.get(url);
          if (response.statusCode == 200) {
            var jsonString = response.body;
            var jsonMap = json.decode(jsonString);
            fixture_model = Live.fromJson(jsonMap);
            print(jsonMap ):                             //--- printed the list in console successfully 
          }
        } catch (Exception) {
          return fixture_model;
        }
      }
    }
    

    我忘记在捕获异常之外返回列表,在我添加返回后它是固定的:

    import 'dart:convert';
    import 'package:http/http.dart' as http;
    import 'package:myexpect/models/match_fixture.dart';
    
    class Api {
      Future<Live> get_fixture() async {
        var fixture_model = null;
        var client = http.Client();
        try {
          var url =
              'https://livescore-api.com/api-client/fixtures/matches.json?key=xxxxxxC&secret=yyyyy&page=1';
          var response = await client.get(url);
          if (response.statusCode == 200) {
            var jsonString = response.body;
            var jsonMap = json.decode(jsonString);
            fixture_model = Live.fromJson(jsonMap);
            print(jsonMap ):                             //--- printed the list in console successfully 
          }
        } catch (Exception) {
          return fixture_model;
        }
    return fixture_model;  //------------I added this line that i forgot :)
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-22
      • 1970-01-01
      • 2019-03-19
      • 2019-12-22
      • 2021-07-18
      • 2021-10-20
      相关资源
      最近更新 更多