尝试从 JSON 文件的最后一个条目检索数据时出错

Error when trying to retrieve data from last entry of JSON file

我正在尝试读取一个 JSON 文件并从最后一个条目中获取一个值以在构建小部件时显示在屏幕上。 JSON 文件存储在本地并已添加到 pubspec.yaml。每次我去我的测试页面查看是否显示该值时,我都会得到下面的错误屏幕截图。我不知道我做错了什么。

这是我的 PODO:

import 'dart:convert';

List<HistoryData> historyDataFromJson(String str) => List<HistoryData>.from(json.decode(str).map((x) => HistoryData.fromJson(x)));

String historyDataToJson(List<HistoryData> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));

class HistoryData {
  HistoryData({
      this.date,
      this.weight,
      this.loss,
      this.change,
  });

  String date;
  String weight;
  String loss;
  String change;

  factory HistoryData.fromJson(Map<String, dynamic> json) => HistoryData(
      date: json["date"],
      weight: json["weight"],
      loss: json["loss"],
      change: json["change"],
  );

  Map<String, dynamic> toJson() => {
      "date": date,
      "weight": weight,
      "loss": loss,
      "change": change,
  };
}

这是将创建我的屏幕的小部件:

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  String current = '';

  void initState() {
    super.initState();
    current = getCurrentWeight();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: Text(current)
      ),
    );
  }

  String getCurrentWeight() {
    List<HistoryData> historyList = historyDataFromJson(rootBundle.loadString('json_files/history.json').toString());
    var history = historyList[historyList.length-1];
    String current = history.weight;
    return current;
  }
}

更新: 根据要求,这是整个 JSON 文件。

[
    {
        "date" : "17/06/2020",
        "weight" : "95.0",
        "loss" : "+0.0",
        "change" : "+0.0"
    },
    {
        "date" : "18/06/2020",
        "weight" : "96.0",
        "loss" : "+1.0",
        "change" : "+1.1"
    },
    {
        "date" : "19/06/2020",
        "weight" : "95.1",
        "loss" : "-0.9",
        "change" : "-0.9"
    },
    {
        "date" : "20/06/2020",
        "weight" : "94.2",
        "loss" : "-0.9",
        "change" : "-0.9"
    },
    {
        "date" : "21/06/2020",
        "weight" : "92.0",
        "loss" : "-2.2",
        "change" : "-2.3"
    },
    {
        "date" : "22/06/2020",
        "weight" : "90.6",
        "loss" : "-1.4",
        "change" : "-1.5"
    },
    {
        "date" : "23/06/2020",
        "weight" : "89.6",
        "loss" : "-1.0",
        "change" : "-1.1"
    },
    {
        "date" : "24/06/2020",
        "weight" : "89.4",
        "loss" : "-0.2",
        "change" : "-0.2"
    },
    {
        "date" : "25/06/2020",
        "weight" : "87.8",
        "loss" : "-1.6",
        "change" : "-1.8"
    },
    {
        "date" : "26/06/2020",
        "weight" : "86.1",
        "loss" : "-1.7",
        "change" : "-1.9"
    }
]

rootBundle.loadString() returns a Future 就像错误暗示的那样。然后你在上面做 toString,这是 Instance of ...,导致你的特定错误,因为那不是 JSON。

您需要 await rootBundle.loadString('json_files/history.json') 的结果:

Future<String> getCurrentWeight() async {
  List<HistoryData> historyList = historyDataFromJson(await rootBundle.loadString('json_files/history.json'));
  var history = historyList[historyList.length-1];
  String current = history.weight;
  return current;
}

然后您必须修改您的小部件以正确处理使用 FutureBuilder 显示此未来数据。

class _TestState extends State<Test> {
  Future<String> current;

  @override
  void initState() {
    super.initState();
    current = getCurrentWeight();//Obtain your future
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: current,//Pass the future
      builder: (context, snapshot) {
        if(snapshot.hasData) {//Show data only when it's available
          return Container(
            child: Center(
              child: Text(snapshot.data)//Obtain data here
            ),
          );
        }
        return CircularProgressIndicator();//Show this otherwise
      }
    );
  }

  Future<String> getCurrentWeight() async {
    List<HistoryData> historyList = historyDataFromJson(await rootBundle.loadString('json_files/history.json'));
    var history = historyList[historyList.length-1];
    String current = history.weight;
    return current;
  }
}