0

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

3 Answers 3

2

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

Thanks.

Sign up to request clarification or add additional context in comments.

3 Comments

where function called API POST
called the api in the initstate, loadyoudata() method checkout
i have loaded the data locally in the assets in the json folder and added your json, this is the sample example for you, in loadyourdata function after the isloading true you can make your api call later after you get the string from the body everything is the same. i have mentioned int he comment.
1

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

3 Comments

thanks. I was added model Content, how to get variable value & looping Text widget is trying to display. please advice me
For example: postResult.content.nomorAccount
This error: Exception has occurred. _TypeError (type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>')
0

I think we need to follow JsonSerializable

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.