Warm tip: This article is reproduced from stackoverflow.com, please click
dart flutter http post

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

发布于 2020-03-27 15:46:11

I want to parsing nested json with flutter http POST. I write my code, and no show data in my ListView.builder

This Request Json:

{
 "nomorAccount": "1234567890"
}

This Json Nested Response

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

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.
how to looping array POST request Result
Please your advice for my problem

Questioner
devel flutt
Viewed
228
Selim Kundakçıoğlu 2020-01-31 18:59

I guess you are trying to parse your json in a wrong way. And you can't get the variables in content. So they probably become null and your Text widget is trying to display a null object

{
  "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']. I would suggest you to create another model called 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

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. 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.

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

Suggestion

Instead of hard coding all of this json classes I would suggest you to use Json Serializable package