【问题标题】:how to show data on listview builder from http POST request Result Flutter如何从http POST请求结果颤振在listview builder上显示数据
【发布时间】:2020-05-16 22:37:41
【问题描述】:

我想用 Flutter http POST 解析嵌套的 json。我编写了代码,但 ListView.builder 中没有显示数据

此请求 Json:

{
 "nomorAccount": "1234567890"
}

这个 Json 嵌套响应

{
  "responseCode": "0000",
  "responseMessage": "Success",
  "tanggal": "20200131",
  "jam": "112301",
  "content": [
    {
      "nomorAccount": "1234567890",
      "namaPegawai": "DEVELOPMENT",
      "statusAccount": "AKTIF",
      "jenisAccount": "TABUNGAN",
      "produkAccount": "GOLD",
      "mataUang": "IDR",
      "saldoEfektif": "+100055033221,84",
      "saldoBuku": "+100055058221,84"
    }
  ]
}

型号

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;


class PostResult {
    String responseCode;
    String responseMessage;
    String tanggal;
    String jam;
    String nomorAccount;
    String namaPegawai;
    String statusAccount;
    String jenisAccount;
    String produkAccount;
    String mataUang;
    String saldoEfektif;
    String saldoBuku;

    PostResult({this.responseCode,this.responseMessage,this.tanggal,this.jam,this.nomorAccount,this.namaPegawai,this.statusAccount,this.jenisAccount,this.produkAccount,this.mataUang,this.saldoEfektif,this.saldoBuku});

    factory PostResult.createPostResult(Map<String, dynamic> object)
    {
      return PostResult(
        responseCode: object['responseCode'],
        responseMessage: object['responseMessage'],
        tanggal: object['tanggal'],
        jam: object['jam'],
        nomorAccount: object['nomorAccount'],
        namaPegawai: object['namaPegawai'],
        statusAccount: object['statusAccount'],
        jenisAccount: object['jenisAccount'],
        produkAccount: object['produkAccount'],
        mataUang: object['mataUang'],
        saldoEfektif:object['saldoEfektif'],
        saldoBuku:object['saldoBuku']
      );
    }

    static Future<PostResult> connectToAPI(String nomorAccount) async {
      String apiURL = "http://contoh.com/api";
      String username = "username";
      String password = "12345678";
      var bytes = utf8.encode("$username:$password");

      var credentials = base64.encode(bytes);
      var headers = {
        "Content-Type": "application/json",
        "Authorization": "Basic $credentials"
      };

      var requestBody = jsonEncode({ 'nomorAccount': nomorAccount});
      http.Response apiResult = await http.post(apiURL, body: requestBody, headers: headers);

      if(apiResult.statusCode == 200){
        apiResult.body;
      } else {
        Exception('gagal memuat data');
      }

      var jsonObject = json.decode(apiResult.body);
      //print(jsonObject);

      return PostResult.createPostResult(jsonObject);
    }
}

还有这个 ui 小部件

class CheckBalance extends StatefulWidget {
  CheckBalanceState createState() => CheckBalanceState();
}

class CheckBalanceState extends State<CheckBalance> {
  PostResult postResult;

  @override
  Widget build(BuildContext context) {
    return new SafeArea(
        child: new Scaffold(
          appBar: BankMantapAppBar(),
          body: SingleChildScrollView(
            child: Padding(
              padding: const EdgeInsets.all(12.0),
              child: Column(
                children: <Widget>[
                  Row(
                    children: <Widget>[
                      RaisedButton(
                        onPressed: (){
                          PostResult.connectToAPI("0002104252033").then((value){
                            postResult = value;
                            setState(() {});
                          });
                        },
                        child: Text('CEK'),
                      ),
                    ],
                  ),
                  Card(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[

                        ListTile(
                          title: Text('nilai return'),
                          subtitle: Column(children: <Widget>[
                            Row(
                              children: <Widget>[
                                Text('response code : ', style: TextStyle(fontWeight: FontWeight.bold),),
                                Text((postResult != null)
                                    ? postResult.responseCode
                                    : "Tidak ada data",
                                  style: TextStyle(fontStyle: FontStyle.italic, fontSize: 15.0),
                                ),
                              ],
                            ),
                            Row(
                              children: <Widget>[
                                Text('return message : ', style: TextStyle(fontWeight: FontWeight.bold),),
                                Text((postResult != null)
                                    ? postResult.responseMessage
                                    : "Tidak ada data",
                                  style: TextStyle(fontStyle: FontStyle.italic, fontSize: 15.0),
                                ),
                              ],
                            ),
                            Row(
                              children: <Widget>[
                                Text('return tanggal : ', style: TextStyle(fontWeight: FontWeight.bold),),
                                Text((postResult != null)
                                    ? postResult.tanggal
                                    : "Tidak ada data",
                                  style: TextStyle(fontStyle: FontStyle.italic, fontSize: 15.0),
                                ),
                              ],
                            ),
                            Row(
                              children: <Widget>[
                                Text('return jam : ', style: TextStyle(fontWeight: FontWeight.bold),),
                                Text((postResult != null)
                                    ? postResult.jam
                                    : "Tidak ada data",
                                  style: TextStyle(fontStyle: FontStyle.italic, fontSize: 15.0),
                                ),
                              ],
                            ),
                            Row(
                              children: <Widget>[
                                Text('return nomorAccount : ', style: TextStyle(fontWeight: FontWeight.bold),),
                                Text((postResult != null)
                                    ? postResult.nomorAccount
                                    : "Tidak ada data",
                                  style: TextStyle(fontStyle: FontStyle.italic, fontSize: 15.0),
                                ),
                              ],
                            ),
                          ],),
                        ),
                      ],
                    ),
                  )
                ],
              ),
            ),
          ),
        )
    );
  }
}

这是我的错误代码

A non-null String must be provided to a Text widget.
'package:flutter/directory/widgets/text.dart':
Failed assertion: line 28510: 'data != null'

我想要做的不是给出值,而是从 POST 请求的结果中获取并显示。
如何循环数组POST请求结果
请您对我的问题提出建议

【问题讨论】:

    标签: http post flutter dart


    【解决方案1】:

    我猜你正试图以错误的方式解析你的 json。而且您无法获取content 中的变量。因此它们可能会变为 null,并且您的 Text 小部件正在尝试显示 null 对象

    {
      "responseCode": "0000",
      "responseMessage": "Success",
      "tanggal": "20200131",
      "jam": "112301",
      "content": [
        {
          "nomorAccount": "1234567890",
          "namaPegawai": "DEVELOPMENT",
          "statusAccount": "AKTIF",
          "jenisAccount": "TABUNGAN",
          "produkAccount": "GOLD",
          "mataUang": "IDR",
          "saldoEfektif": "+100055033221,84",
          "saldoBuku": "+100055058221,84"
        }
      ]
    }
    

    您正试图通过像object['nomorAccount'] 一样直接调用来获取content 变量下的变量。我建议您创建另一个名为 Content

    的模型
    class Content {
      String nomorAccount;
      String namaPegawai;
      String statusAccount;
      String jenisAccount;
      String produkAccount;
      String mataUang;
      String saldoEfektif;
      String saldoBuku;
    
      Content({
        this.nomorAccount,
        this.namaPegawai,
        this.statusAccount,
        this.jenisAccount,
        this.produkAccount,
        this.mataUang,
        this.saldoEfektif,
        this.saldoBuku});
    
      factory Content.fromJson(Map<String, dynamic> json) {
        return Content (
          nomorAccount: json['nomorAccount'],
          namaPegawai: json['namaPegawai'],
          statusAccount: json['statusAccount'],
          jenisAccount: json['jenisAccount'],
          produkAccount: json['produkAccount'],
          mataUang: json['mataUang'],
          saldoEfektif:json['saldoEfektif'],
          saldoBuku:json['saldoBuku']
      );
    }
    

    在你的 PostResult 模型中

    class PostResult {
      String responseCode;
      String responseMessage;
      String tanggal;
      String jam;
      Content content;
    
      PostResult(
          {this.responseCode,
          this.responseMessage,
          this.tanggal,
          this.jam,
          this.content});
    
      factory PostResult.createPostResult(Map<String, dynamic> object) {
        return PostResult(
          responseCode: object['responseCode'],
          responseMessage: object['responseMessage'],
          tanggal: object['tanggal'],
          jam: object['jam'],
          content: Content.fromJson(object['content']),
        );
      }
    
      yourConnectToApiFunction()
    }
    

    编辑:

    我没有意识到您的 JSON 返回一个只有一项内容的数组。如果它总是返回一个项目,您可以更改您的 API 以使其只是一个对象而不是数组,并保持 dart 代码不变。

    如果在任何情况下,它会返回多个对象,您需要更改模型,如下所示:

    class PostResult {
      String responseCode;
      String responseMessage;
      String tanggal;
      String jam;
      List<Content> content;
    
      PostResult(
          {this.responseCode,
          this.responseMessage,
          this.tanggal,
          this.jam,
          this.content});
    
      factory PostResult.createPostResult(Map<String, dynamic> object) {
        return PostResult(
          responseCode: object['responseCode'],
          responseMessage: object['responseMessage'],
          tanggal: object['tanggal'],
          jam: object['jam'],
          content: (object['content'] as List)
              .map((e) => Content.fromJson(e as Map<String, dynamic>))
              .toList(),
        );
      }
    
      yourConnectToApiFunction()
    }
    

    然后你就可以像responseObject.content[0].nomorAccount这样得到你的项目了

    建议

    建议您使用Json Serializable 包,而不是对所有这些 json 类进行硬编码

    【讨论】:

    • 谢谢。我添加了模型内容,如何获取变量值和循环文本小部件正在尝试显示。请给我建议
    • 例如:postResult.content.nomorAccount
    • 此错误:发生异常。 _TypeError(类型 'List' 不是类型 'Map' 的子类型)
    【解决方案2】:

    看看下面的例子

    import 'package:flutter/material.dart';
    import 'dart:async';
    import 'package:flutter/services.dart';
    import 'package:flutter_sound_example/models.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      List<Content> dataList = List();
      bool _isLoading = false;
      BuildContext context1;
    
      Future<String> loadFromAssets() async {
        return await rootBundle.loadString('json/parse.json');
      }
    
      Future loadyourData() async {
        setState(() {
          _isLoading = true;
        });
    
    // this is the local json that i have loaded from the assets folder
    // you can make the http call here and else everything later is the same.
    
        String jsonString = await loadFromAssets();
        final content = contentFromJson(jsonString);
        dataList.add(content);
    
        setState(() {
          _isLoading = false;
        });
      }
    
      @override
      void initState() {
        super.initState();
    
        loadyourData();
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
            home: Scaffold(
          body: _isLoading
              ? CircularProgressIndicator()
              : ListView.builder(
                  itemCount: dataList.length,
                  itemBuilder: (context, index) {
                    return Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: Card(
                        child: Column(
                          children: <Widget>[
                            // insert your tree accordingly
                            Text(dataList[index].tanggal),
                            Text(dataList[index].content[0].jenisAccount)
                          ],
                        ),
                      ),
                    );
                  },
                ),
        ));
      }
    }
    
    

    这是上面的主页

    // To parse this JSON data, do
    //
    //     final content = contentFromJson(jsonString);
    
    import 'dart:convert';
    
    Content contentFromJson(String str) => Content.fromJson(json.decode(str));
    
    String contentToJson(Content data) => json.encode(data.toJson());
    
    class Content {
      String responseCode;
      String responseMessage;
      String tanggal;
      String jam;
      List<ContentElement> content;
    
      Content({
        this.responseCode,
        this.responseMessage,
        this.tanggal,
        this.jam,
        this.content,
      });
    
      factory Content.fromJson(Map<String, dynamic> json) => Content(
            responseCode: json["responseCode"],
            responseMessage: json["responseMessage"],
            tanggal: json["tanggal"],
            jam: json["jam"],
            content: List<ContentElement>.from(
                json["content"].map((x) => ContentElement.fromJson(x))),
          );
    
      Map<String, dynamic> toJson() => {
            "responseCode": responseCode,
            "responseMessage": responseMessage,
            "tanggal": tanggal,
            "jam": jam,
            "content": List<dynamic>.from(content.map((x) => x.toJson())),
          };
    }
    
    class ContentElement {
      String nomorAccount;
      String namaPegawai;
      String statusAccount;
      String jenisAccount;
      String produkAccount;
      String mataUang;
      String saldoEfektif;
      String saldoBuku;
    
      ContentElement({
        this.nomorAccount,
        this.namaPegawai,
        this.statusAccount,
        this.jenisAccount,
        this.produkAccount,
        this.mataUang,
        this.saldoEfektif,
        this.saldoBuku,
      });
    
      factory ContentElement.fromJson(Map<String, dynamic> json) => ContentElement(
            nomorAccount: json["nomorAccount"],
            namaPegawai: json["namaPegawai"],
            statusAccount: json["statusAccount"],
            jenisAccount: json["jenisAccount"],
            produkAccount: json["produkAccount"],
            mataUang: json["mataUang"],
            saldoEfektif: json["saldoEfektif"],
            saldoBuku: json["saldoBuku"],
          );
    
      Map<String, dynamic> toJson() => {
            "nomorAccount": nomorAccount,
            "namaPegawai": namaPegawai,
            "statusAccount": statusAccount,
            "jenisAccount": jenisAccount,
            "produkAccount": produkAccount,
            "mataUang": mataUang,
            "saldoEfektif": saldoEfektif,
            "saldoBuku": saldoBuku,
          };
    }
    
    

    这是你想要的模型类。

    {
        "responseCode": "0000",
        "responseMessage": "Success",
        "tanggal": "20200131",
        "jam": "112301",
        "content": [
          {
            "nomorAccount": "1234567890",
            "namaPegawai": "DEVELOPMENT",
            "statusAccount": "AKTIF",
            "jenisAccount": "TABUNGAN",
            "produkAccount": "GOLD",
            "mataUang": "IDR",
            "saldoEfektif": "+100055033221,84",
            "saldoBuku": "+100055058221,84"
          }
        ]
      }
    

    这是我在本地加载的 json 查看示例并告诉我

    谢谢。

    【讨论】:

    • 函数调用API POST
    • 在initstate调用api,loadyoudata()方法checkout
    • 我已经在 json 文件夹的 assets 中本地加载了数据并添加了你的 json,这是给你的示例示例,在 isloading true 之后的 loadyourdata 函数中,你可以稍后调用你的 api从正文中获取字符串一切都是一样的。我在他的评论中提到过。
    【解决方案3】:

    我认为我们需要关注JsonSerializable

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
    猜你喜欢
    • 2020-07-03
    • 2022-11-03
    • 2020-11-10
    • 1970-01-01
    • 2020-11-09
    • 2021-05-01
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多