无法在Future Builder中显示解析的JSON

Posted

技术标签:

【中文标题】无法在Future Builder中显示解析的JSON【英文标题】:Unable to display the parsed JSON in Future Builder in flutter 【发布时间】:2021-09-21 04:35:28 【问题描述】:

我试图从 REST API 获取数据结果,然后将其显示在 UI 中。 所以一切都很顺利,JSON 被很好地解析,try 和 catch 方法工作正常。 但不知何故,代码无法在 UI 中显示解析结果。 它都没有给我一个错误或异常。 在过去的几天里,我一直在努力达到预期的结果。

这是 JSON 的样子:


    "data-description": "This api will return an array of objects to be placed in the order status timeline on the second screen",
    "order-status": "Success",
    "status-objects": [
        
            "type": "Payment",
            "status": "completed",
            "date": "2021-07-02T00:00:00",
            "time": "12:00AM"
        ,
        
            "type": "Units Allocated",
            "status": "by Axis",
            "date": "2021-07-13T00:00:00",
            "time": "12:00AM"
        
    ]

这样做后我想实现什么类型的 UI。

为了让问题更清楚,我将附上我的代码sn-ps。

模型类

Transaction transactionFromJson(String str) =>
    Transaction.fromJson(json.decode(str));

String transactionToJson(Transaction data) => json.encode(data.toJson());

class Transaction 
  Transaction(
    required this.dataDescription,
    required this.orderStatus,
    required this.statusObjects,
  );

  String dataDescription;
  String orderStatus;
  List<StatusObject> statusObjects;

  factory Transaction.fromJson(Map<String, dynamic> json) => Transaction(
        dataDescription: json["data-description"],
        orderStatus: json["order-status"],
        statusObjects: List<StatusObject>.from(
            json["status-objects"].map((x) => StatusObject.fromJson(x))),
      );

  Map<String, dynamic> toJson() => 
        "data-description": dataDescription,
        "order-status": orderStatus,
        "status-objects":
            List<dynamic>.from(statusObjects.map((x) => x.toJson())),
      ;


class StatusObject 
  StatusObject(
    required this.type,
    required this.status,
    required this.date,
    required this.time,
  );

  String type;
  String status;
  DateTime date;
  String time;

  factory StatusObject.fromJson(Map<String, dynamic> json) => StatusObject(
        type: json["type"],
        status: json["status"],
        date: DateTime.parse(json["date"]),
        time: json["time"],
      );

  Map<String, dynamic> toJson() => 
        "type": type,
        "status": status,
        "date": date.toIso8601String(),
        "time": time,
      ;

进行解析和获取的API_Manager 服务类

class API_Manager 
  static Future<Transaction> getDetails() async 
    var client = http.Client();
    var transactions;
    try 
      var response = await client.get(
          Uri.https("https://hereistheurl", "/accounts/test-data/"));

      if (response.statusCode == 200) 
        var jsonString = response.body;
        var jsonMap = jsonDecode(jsonString);
        transactions = Transaction.fromJson(jsonMap);
      
     catch (e) 
      return transactions;
    
    return transactions;
  

我想要显示解析后的 JSON 的 UI 组件:

代码

FutureBuilder<Transaction>(
                  future: API_Manager.getDetails(),
                  builder: (context, snapshot) 
                    if (snapshot.hasData) 
                      var data = snapshot.data!.statusObjects;
                      return ListView.builder(
                        itemCount: data.length,
                        itemBuilder: (context, index) =>
                            Text('$index : $data[index].status'),
                      );
                    
                    return Text('Something was wrong!');
                  ,
                ),
              

我很确定我遗漏了一小段代码来使它工作。 我已经在这段代码上工作了好几天,但无法做到。 我请求你们,请帮助我获得结果或指出我遗漏的代码。

如果您能以任何可能的方式帮助我,我们将不胜感激。

【问题讨论】:

能否提供更完整的样本数据集进行测试? 还有生成_transactions的代码 您可以将 JSON 用于数据集。这是生成 _transactions 的代码:late Future _transactions; @override void initState() _transactions = API_Manager().getDetails(); super.initState(); @ΟυιλιαμΑρκευα 请帮助我理解这一点。 【参考方案1】:

兄弟,您错误地使用了*builder 小部件,我已对您的代码进行了一些更正:

服务类

typedef JMap = Map<String, dynamic>;

class API_Manager 
  static Future<Transaction> getData() 
    return Future.delayed(Duration(seconds: 1), () => raw_response)
      .then((response) 
        return Transaction.fromJson(jsonDecode(response) as JMap);
      );
  


const raw_response = '''

  "data-description": "This api will return an array of objects to be placed in the order status timeline on the second screen",
  "order-status": "Success",
  "status-objects": [
...
  ]

''';

演示文稿

class HomePage extends StatelessWidget 
  const HomePage(Key? key) : super(key: key);
  @override
  Widget build(BuildContext context) 
    return Scaffold(
      appBar: AppBar(
        title: Text('Hi!'),
        centerTitle: true,
      ),
      body: Container(
        child: FutureBuilder<Transaction>(
          future: API_Manager.getData(),
          builder: (context, snapshot) 
            if (snapshot.hasError) 
              return Text(snapshot.error.toString());
            if (snapshot.connectionState == ConnectionState.waiting) 
              return Center(child: CircularProgressIndicator());
            if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) 
              final data = snapshot.data!.statusObjects;
              return ListView.builder(
                itemCount: data.length,
                itemBuilder: (context, index) => Text('$index : $data[index].status'),
              );
            
            return Text('Something was wrong!');
          ,
        ),
      ),
    );
  

结果:

更新(1)

  static Future<Transaction?> getDetails(String url) 
    return http.get(Uri.parse(url))
      .then((response) 
        if (response.statusCode == 200) 
          return Transaction.fromJson(jsonDecode(response.body) as JMap);
        return null;
      )
      .catchError((err)  print(err); );
  

【讨论】:

我尝试更新代码,但仍然收到错误显示消息:类型“Null”不是“FutureOr”类型的子类型。我已经更新了代码请检查 现在更新的输出打印:出了点问题! 问题在于您的getDetails 函数,您正试图返回一个非未来值,您必须将该函数修改为类似于我的getData 函数。 我对在 Flutter 代码中集成 REST API 很陌生。您介意按照我编写的代码帮助我理解 getData 代码吗?请提出要求 代码已更新。兄弟,你需要了解更多关于如何使用 Dart

以上是关于无法在Future Builder中显示解析的JSON的主要内容,如果未能解决你的问题,请参考以下文章

解析 Future Builder 时出错:TypeError: Cannot read property 'Symbol(dartx._get)' of null

如何使用 Flutter 数据模型和 Future Builder

REST GET 在 Future Builder 中返回无效参数

为啥 Future.Builder 中的快照从不出错?

Flutter + Hive 检查 Future Builder 的框中是不是存在值

如何在颤动中计算 GridView.builder 的 childAspectRatio