如何从http POST请求结果颤振在listview builder上显示数据

Posted

技术标签:

【中文标题】如何从http POST请求结果颤振在listview builder上显示数据【英文标题】:how to show data on listview builder from http POST request Result Flutter 【发布时间】: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请求结果 请您对我的问题提出建议

【问题讨论】:

【参考方案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。

以上是关于如何从http POST请求结果颤振在listview builder上显示数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤振小部件测试中发出 http 请求?

如何在颤振集成测试中模拟 http 请求?

如何防止颤振应用程序在 Dio 错误后崩溃?

颤振 http 标头

在使用 Hive 进行颤振时,您如何将自定义对象从 POST 响应正文添加到框?

颤振从单元\小部件测试调用http请求而不进行模拟