如何在 FutureBuilder 中解析从本地主机接收的 JSON 对象

Posted

技术标签:

【中文标题】如何在 FutureBuilder 中解析从本地主机接收的 JSON 对象【英文标题】:How do I resolve a JSON object received from localhost in FutureBuilder 【发布时间】:2021-08-03 14:52:37 【问题描述】:

我在 localhost 上托管了以下 JSON,并尝试在 FutureBuilder 小部件中解决它。我无法解析来自 Json 的数据以使用 FutureBuilder 小部件显示。我得到的只是“LiteratureDataModel 的实例”。此外,我无法获得数据快照的长度。我得到的错误是“没有为对象类型定义吸气剂长度”


    "data": [
        
            "authors": "author_name1",
            "edition": "publication_edition1",
            "id": 1,
            "pubdate": "publication_date1",
            "publisher": "publisher1",
            "source": "literature_source1",
            "title": "literature_title1"
        ,
    
            "authors": "author_name2",
            "edition": "publication_edition2",
            "id": 2,
            "pubdate": "publication_date2",
            "publisher": "publisher2",
            "source": "literature_source2",
            "title": "literature_title2"
        
    ]

我使用以下链接为上述 Json 生成了模型类:

https://app.quicktype.io/

这是生成的类。我对其进行了修改以使用空安全性。根据 JSON 的地图对象列表在literatureDataModel 工厂构造函数中成功打印。至此,数据接收成功

class LiteratureDataModel 
  LiteratureDataModel(
    this.ultLiteratureDataModel,
  );

  final List<LiteratureModel>? ultLiteratureDataModel;

  factory LiteratureDataModel.fromJson(Map<String, dynamic> json) => LiteratureDataModel(
    ultLiteratureDataModel: List<LiteratureModel>.from(json["data"].map((data) 
      print(data);
      return LiteratureModel.fromJson(data);
    )).toList(),
  );

  Map<String, dynamic> toJson() => 
    "data": List<dynamic>.from(ultLiteratureDataModel!.map((data) => data.toJson())),
  ;


class LiteratureModel 
  LiteratureModel(
    this.authors,
    this.edition,
    this.id,
    this.pubdate,
    this.publisher,
    this.source,
    this.title,
  );

  final String? authors;
  final String? edition;
  final int? id;
  final String? pubdate;
  final String? publisher;
  final String? source;
  final String? title;

  factory LiteratureModel.fromJson(Map<String, dynamic> json) => LiteratureModel(
    authors: json["authors"],
    edition: json["edition"],
    id: json["id"],
    pubdate: json["pubdate"],
    publisher: json["publisher"],
    source: json["source"],
    title: json["title"],
  );

  Map<String, dynamic> toJson() => 
    "authors": authors,
    "edition": edition,
    "id": id,
    "pubdate": pubdate,
    "publisher": publisher,
    "source": source,
    "title": title,
  ;

这是显示数据的小部件:

class Literature extends StatelessWidget 

  final LiteratureService _literatureService = LiteratureService();

  @override
  Widget build(BuildContext context) 
    return Padding(
      padding: const EdgeInsets.all(24.0),
      child: Container(
        decoration: BoxDecoration(
          color: Colors.white,
          borderRadius: BorderRadius.all(Radius.circular(12)),
        ),
        child: Center(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: FutureBuilder(
                future: _literatureService.fetchLiterature(http.Client()),
                builder: (context, snapshot)
                  if (snapshot.hasData)
                    //return Text("$snapshot.data!");
                    return ListView.builder(
                      //itemCount: snapshot.data!.length,
                        itemBuilder: (context, index)
                      return Text("$snapshot.data!");
                    );
                  else
                    return CircularProgressIndicator();
                ,
              ),
            )
        ),
      ),
    );
  

json 托管在 localhost 上,我可以从中成功提取 json。这是用于从本地主机获取 json 的类

class LiteratureService 
  LiteratureDataModel literatureFromJson(String literature) 
    //print(literature);
    return LiteratureDataModel.fromJson(json.decode(literature));
  

  String literatureToJson(LiteratureDataModel literatureDataModel) => json.encode(literatureDataModel.toJson());

  Future fetchLiterature(http.Client client) async 
    final response = await client.get(Uri.parse("http://localhost_ip_address:8000/literature/ultliterature.json"));
    //print("Http response: $response.body");
    return literatureFromJson(response.body);
  

我参考以下链接解决了这个问题,但无法解决:

*SOLVED* Use json data stored in class in future builder

在上面的链接中,OP 遇到了与我类似的问题。我遵循了正确答案中建议的更改,但意识到它只是另一种创建工厂构造函数的方法,它存在于literatureDataModel 类中。而且,我仍然无法获得数据快照的长度。

我也参考了下面的链接,里面也展示了 JSON 序列化和反序列化的不同方式,仍然无法解决问题。

https://bezkoder.com/dart-flutter-parse-json-string-array-to-object-list/#DartFlutter_parse_JSON_string_into_Nested_Object

我在代码中做错了什么?对我的代码进行必要更正的任何建议都会有所帮助。

【问题讨论】:

【参考方案1】:

我通过省略LiteratureDataModel 类并按以下方式更改fetchLiterature() 函数解决了这个问题:

Future<List<LiteratureModel>> fetchLiterature(http.Client client) async 
    final response =
        await client.get(Uri.parse("http://localhost_ip_address:8000/literature/literature.json"));
    List<LiteratureModel> literatureModel = List<LiteratureModel>.from(
        json.decode(response.body)["data"].map((data) => LiteratureModel.fromJson(data)).toList());
    return literatureModel;
  

我还使用 link 作为指南对 FutureBuilder 进行了以下更改

builder: (context, AsyncSnapshot&lt;List&lt;LiteratureModel&gt;&gt; snapshot)

如果有人知道解决我发布的问题的更好方法,请告诉我

【讨论】:

以上是关于如何在 FutureBuilder 中解析从本地主机接收的 JSON 对象的主要内容,如果未能解决你的问题,请参考以下文章

如何在 FutureBuilder() 中正确“刷新”小部件

如何在 FutureBuilder Flutter 中停止循环 SetState

如何创建一个 Flutter Futurebuilder 函数来显示从 JSON 中获取的字符串数组?

使用带有本地 JSON 作为未来的 FutureBuilder 时出错

在这种情况下,如何在 Flutter 中正确实现 FutureBuilder?

我如何在 FutureBuilder Widget 的构建器函数中等待 - Flutter