简体   繁体   English

如何从 http POST 请求结果 Flutter 在列表视图构建器上显示数据

[英]how to show data on listview builder from http POST request Result Flutter

I want to parsing nested json with flutter http POST.我想用 flutter http POST 解析嵌套的 json。 I write my code, and no show data in my ListView.builder我写了我的代码,但在我的 ListView.builder 中没有显示数据

This Request Json:此请求 Json:

{
 "nomorAccount": "1234567890"
}

This Json Nested Response这个 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"
    }
  ]
}

Model模型

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);
    }
}

and this ui widget还有这个 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),
                                ),
                              ],
                            ),
                          ],),
                        ),
                      ],
                    ),
                  )
                ],
              ),
            ),
          ),
        )
    );
  }
}

this my error code这是我的错误代码

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

what I am trying to do is rather than giving values, I want it to take from the result of the POST request and display.我想要做的不是给出值,而是希望它从 POST 请求和显示的结果中获取。
how to looping array POST request Result如何循环数组POST请求结果
Please your advice for my problem请您对我的问题提出建议

I guess you are trying to parse your json in a wrong way.我猜你正试图以错误的方式解析你的 json。 And you can't get the variables in content .而且您无法获取content的变量。 So they probably become null and your Text widget is trying to display a null object所以它们可能会变成 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"
    }
  ]
}

You are trying to get variables under content variable by calling directly like object['nomorAccount'] .您试图通过直接调用object['nomorAccount']来获取content变量下的变量。 I would suggest you to create another model called 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']
  );
}

And inside your PostResult model在你的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()
}

EDIT:编辑:

I didn't realize that your JSON returns an array with only one item for content.我没有意识到您的 JSON 返回一个数组,其中只有一项内容。 If it always returns one item you can change your API to make it just an object instead of an array and leave the dart code as it is.如果它总是返回一个项目,您可以更改您的 API 以使其只是一个对象而不是数组,并保持 dart 代码不变。

If in any case, it returns more than one object you need to change your model like below:如果在任何情况下,它都会返回多个您需要更改模型的对象,如下所示:

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()
}

And then you can get your item like responseObject.content[0].nomorAccount然后你可以得到你的项目,比如responseObject.content[0].nomorAccount

Suggestion建议

Instead of hard coding all of this json classes I would suggest you to use Json Serializable package我建议您使用Json Serializable包,而不是硬编码所有这些 json 类

check out the example below看看下面的例子

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)
                      ],
                    ),
                  ),
                );
              },
            ),
    ));
  }
}

this is the main page above这是上面的主页

// 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,
      };
}

this is the model class you want.这是您想要的模型类。

{
    "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"
      }
    ]
  }

this is the json i have loaded locally check out the example and let me know这是我在本地加载的 json 查看示例并让我知道

Thanks.谢谢。

我认为我们需要遵循JsonSerializable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM