Home > Blockchain >  How can I implement listview.builder in FutureBuilder in Scaffold block?
How can I implement listview.builder in FutureBuilder in Scaffold block?

Time:09-17

I want to add my data in listview. also tried using this https://flutter.dev/docs/cookbook/lists/long-lists

I got data in futureAlbum, and snapshot has data. but i can't convert these data in listView.builder. so, how to implement listview in FutureBuilder?

body: Center(
        child: FutureBuilder<ListAlbum>(
          future: futureAlbum,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              print(snapshot.data);
              return Text(snapshot.data!.idEmployee.toString()); // in this section i want to add listview
            } else if (snapshot.hasError) {
              return Text('${snapshot.error}');
            }
            return const CircularProgressIndicator();
          },
        ),
      ),

full code of calling api

class OrganizationList extends StatefulWidget {
  const OrganizationList({Key? key}) : super(key: key);

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

class _OrganizationListState extends State<OrganizationList> {
  late Future<ListAlbum> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = listData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<ListAlbum>(
          future: futureAlbum,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              print(snapshot.data);
              return Text(snapshot.data!.idEmployee.toString()); // in this section i want to add listview
            } else if (snapshot.hasError) {
              return Text('${snapshot.error}');
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}


class ListAlbum {
  final int idEmployee;
  final String avatar;
  final String fullName;
  final String officeID;
  final String email;
  final String designation;
  final String department;
  final String mobileNumber;
  final String workStation;
  final String businessUnit;

  ListAlbum({
    required this.idEmployee,
    required this.avatar,
    required this.fullName,
    required this.officeID,
    required this.email,
    required this.designation,
    required this.department,
    required this.mobileNumber,
    required this.workStation,
    required this.businessUnit,
  });

  factory ListAlbum.fromJson(Map<String, dynamic> json) {
    return ListAlbum(
      idEmployee: json['idEmployee'],
      avatar: json['avatar'],
      fullName: json['fullName'],
      officeID: json['officeID'],
      email: json['email'],
      designation: json['designation'],
      department: json['department'],
      mobileNumber: json['mobileNumber'],
      workStation: json['workStation'],
      businessUnit: json['businessUnit'],
    );
  }
}

Future<ListAlbum> listData() async {
  final token =
      'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5NTI2OTc1LCJleHAiOjE2Mjk2MTMzNzUsIm5iZiI6MTYyOTUyNjk3NSwianRpIjoiRktiT295eEYwaEpDUXMxdiJ9.o4eM_C4hlluHe9Azk0MspPJtYZ7agdpFA6xwKiijLj8';
  String url =
      'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 5, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);
    var data = ListAlbum.fromJson(response.data["data"]["data"][0]);
    return data;
  } else {
    throw Exception('Failed!');
  }
}

What list I want to implement!

CodePudding user response:

First, you have all members is ListAlbum marked as required, but some of your results in the response doesn't have all of these, for example second row has no avatar. You can overcome this by marking these fields as not required, like this (I made here all members optional - adjust it as you need):

class ListAlbum {
  final int? idEmployee;
  final String? avatar;
  final String? fullName;
  final String? officeID;
  final String? email;
  final String? designation;
  final String? department;
  final String? mobileNumber;
  final String? workStation;
  final String? businessUnit;

  ListAlbum({
    this.idEmployee,
    this.avatar,
    this.fullName,
    this.officeID,
    this.email,
    this.designation,
    this.department,
    this.mobileNumber,
    this.workStation,
    this.businessUnit,
  });

  factory ListAlbum.fromJson(Map<String, dynamic> json) {
    return ListAlbum(
      idEmployee: json['idEmployee'],
      avatar: json['avatar'],
      fullName: json['fullName'],
      officeID: json['officeID'],
      email: json['email'],
      designation: json['designation'],
      department: json['department'],
      mobileNumber: json['mobileNumber'],
      workStation: json['workStation'],
      businessUnit: json['businessUnit'],
    );
  }
}

Next, convert your listData function so that it will return a list of ListAlbum objects. You can grab the data from your response, convert and return like this:

Future<List<ListAlbum>> listData() async {
  final token =
      'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5NTI2OTc1LCJleHAiOjE2Mjk2MTMzNzUsIm5iZiI6MTYyOTUyNjk3NSwianRpIjoiRktiT295eEYwaEpDUXMxdiJ9.o4eM_C4hlluHe9Azk0MspPJtYZ7agdpFA6xwKiijLj8';
  String url =
      'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 5, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);

    return response.data["data"]["data"]
        .map<ListAlbum>((json) => ListAlbum.fromJson(json))
        .toList();
  } else {
    throw Exception('Failed!');
  }
}

Finally, change the future return type and create the ListView from this list, this is an example, adjust it:

class _OrganizationListState extends State<OrganizationList> {
  late Future<List <ListAlbum>> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = listData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Center(
      child: FutureBuilder<List<ListAlbum>>(
        future: futureAlbum,
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            print(snapshot.data);

            return ListView.builder(
              itemCount: snapshot.data!.length,
              itemBuilder: (context, index) {
                final ListAlbum item = snapshot.data![index];
                return ListTile(
                  leading: Text(item.idEmployee.toString()),
                  title: Text(item.fullName!),
                  subtitle: Text(item.designation!),
                  trailing: Text(item.businessUnit!),
                );
              },
            );
          } else if (snapshot.hasError) {
            return Text('${snapshot.error}');
          }
          return const CircularProgressIndicator();
        },
      ),
    ));
  }
}

...and I don't know whether token is a secret or not, but if it is, you should revoke it.

CodePudding user response:

Try this:

Future<List<ListAlbum>> listData() async {
  final token =
      'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjI4OTksImlzcyI6Imh0dHBzOi8vcG9ydGFsLWFwaS5qb21ha2hhdGEuY29tL2FwaS9hdXRoL2xvZ2luIiwiaWF0IjoxNjI5NTI2OTc1LCJleHAiOjE2Mjk2MTMzNzUsIm5iZiI6MTYyOTUyNjk3NSwianRpIjoiRktiT295eEYwaEpDUXMxdiJ9.o4eM_C4hlluHe9Azk0MspPJtYZ7agdpFA6xwKiijLj8';
  String url =
      'https://portal-api.jomakhata.com/api/getOrganizationData?token=${token}';

  Dio dio = new Dio();
  dio.options.headers['Content-Type'] = 'application/json';
  final body = {'limit': 5, 'orderBy': 'idEmployee', 'orderType': 'DESC'};
  final response = await dio.post(url, data: body);

  if (response.statusCode == 200) {
    print(response.statusCode);
    print(response.data);
    List<ListAlbum> _list=response.data["data"]["data"].map((e)=>ListAlbum.fromJson(e)).toList();
  
    return _list;
  } else {
    throw Exception('Failed!');
  }
}

And your widget to this:

class OrganizationList extends StatefulWidget {
  const OrganizationList({Key? key}) : super(key: key);

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

class _OrganizationListState extends State<OrganizationList> {
  late Future<List<ListAlbum>> futureAlbum;

  @override
  void initState() {
    super.initState();
    futureAlbum = listData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder<List<ListAlbum>>(
          future: futureAlbum,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              print(snapshot.data);
              return Column(
              children:[
                for(ListAlbum item in snapshot.data)
                   Text(item.idEmployee.toString())]);
     //Or you can also use listview.builder here instead of column, but this will work for proof of concept.
            } else if (snapshot.hasError) {
              return Text('${snapshot.error}');
            }
            return const CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

  • Related