Search code examples
mysqlflutterdartflutter-futurebuilder

Flutter, how to get data array of object and show to ListView.builder?


im new in flutter and i want to get my data from localhost phpmydmin. here is my json:

{
    "status": true,
    "message": "Data ditemukan",
    "data": [
        {
            "id": "1",
            "username": "admin",
            "password": "d033e22ae348aeb5660fc2140aec35850c4da997",
            "nama": "admin",
            "token": "2a5c97cb31308b8d818da33a041fa47d"
        },
        {
            "id": "3",
            "username": "sani",
            "password": "86862f0600c8b9829d9ca9c8aaca3f0727b44b6e",
            "nama": "Sani Sandhika",
            "token": "661e23835d27f9d45cf371f59533f163"
        },
        {
            "id": "4",
            "username": "seno",
            "password": "d61a4fe61485d6437b698c11635d8fb8c5b79d2f",
            "nama": "Seno",
            "token": "7b9f0f54ca01c323bc810206adcaa38c"
        },
        {
            "id": "5",
            "username": "username",
            "password": "5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8",
            "nama": "nama",
            "token": null
        }
    ]
}

and here is my UserModel:

import 'dart:convert';

List<User> allUsers(String str) {
  final jsonData = json.decode(str);
  return new List<User>.from(jsonData.map((x) => User.fromJson(x)));
}

class User {
  bool status;
  String message;
  List<Data> data;

  User({
    this.status,
    this.message,
    this.data,
  });

  factory User.fromJson(Map<String, dynamic> parsedJson) {
    var list = parsedJson['data'] as List;
    print(list.runtimeType);
    List<Data> dataList = list.map((i) => Data.fromJson(i)).toList();

    return User(
      status: parsedJson['status'],
      message: parsedJson['message'],
      data: dataList,
    );
  }
}

class Data {
  final int id;
  final String nama;
  final String username;

  Data({
    this.id,
    this.nama,
    this.username,
  });

  factory Data.fromJson(Map<String, dynamic> parsedJson) {
    return Data(
      id: parsedJson['id'],
      nama: parsedJson['nama'],
      username: parsedJson['username'],
    );
  }
}

this is my RestApi:

import 'package:flutter_rest_api_crud/models/models.dart';

import 'package:http/http.dart' as http;

class RestApi {
  String url = 'http://192.168.1.5/gizi/user/';

  Future<List<User>> getUsers() async {
    final response = await http.get('$url/user');
    print(response.body);
    return allUsers(response.body);
  }
}

and last here is my HomeScreen:

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

class HomeScreen extends StatefulWidget {
  HomeScreen({Key key}) : super(key: key);

  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
    );
  }
}

And i want to get my data inside "data" from localhost phpmyadmin. and put it on ListView.builder. and i don't know what the next step to implement the listview to my homescreen. anyone can help me ?


Solution

  • You can hit the API endpoint after initializing the Widget:

     List<User> _users = [];
      @override
      void initState() {
        super.initState();
        _load();
      }
    
      void _load() async {
        List<User> users =
            await RestApi.getUsers(); // load the users on Widget init
        setState(() => _users = users);
      }
    

    Then display a nested ListView to display each User's Data:

        return Scaffold(
          appBar: AppBar(),
          body: new ListView.builder(
            itemCount: _users.length,
            itemBuilder: (BuildContext ctxt, int i) {
              return new Card(
                child: Column(
                  children: [
                    Text(_users[i].username),
                    ListView.builder(
                      itemCount: _users[i].data.length,
                      itemBuilder: (BuildContext ctx, int j) {
                        return Text(_users[i]
                            .data[j]
                            .username); // display username as an example
                      },
                    ),
                  ],
                ),
              );
            },
          ),
        );
    

    Follows a full example:

    class _HomeScreenState extends State<HomeScreen> {
      List<User> _users = [];
      @override
      void initState() {
        super.initState();
        _load();
      }
    
      void _load() async {
        List<User> users =
            await RestApi.getUsers(); // load the users on Widget init
        setState(() => _users = users);
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: new ListView.builder(
            itemCount: _users.length,
            itemBuilder: (BuildContext ctxt, int i) {
              return new Card(
                child: Column(
                  children: [
                    Text(_users[i].username),
                    ListView.builder(
                      itemCount: _users[i].data.length,
                      itemBuilder: (BuildContext ctx, int j) {
                        return Text(_users[i]
                            .data[j]
                            .username); // display username as an example
                      },
                    ),
                  ],
                ),
              );
            },
          ),
        );
      }
    }
    

    As your app gets more complicated, I'd suggest checking out different State Management strategies, such as BLoC.