Search code examples
flutterlistview

How to display data api in flutter


permission to ask, I'm trying to display data into a listview and I've managed to get the data seen from the response console below but the data doesn't appear in the UI, is there something I missed or was there something wrong in my writing. Thank you.

this is when i do a data API call

class ListDosenProvider extends ChangeNotifier {
  static Future<List<ModelDosen>> getDosen() async {
    String url = Constant.baseURL;
    String token = await UtilSharedPreferences.getToken();
    final response = await http.get(
      Uri.parse(
        '$url/auth/mhs_siakad/dosen',
      ),
      headers: {
        'Authorization': 'Bearer $token',
      },
    );
    print(response.statusCode);
    print(response.body);
    if (response.statusCode == 200) {
      final List result = json.decode(response.body);
      return result.map((e) => ModelDosen.fromJson(e)).toList();
      // return ModelDosen.fromJson(jsonDecode(response.body));
    } else {
      throw Exception();
    }
  }
}

and this is when i call it inside the widget

import 'package:flutter/material.dart';
import '../../../models/dosen/dosen_model.dart';
import '../../../provider/dosen/dosen_provider.dart';
import '../../../theme.dart';
import '../../../widgets/custom_appbar.dart';

class DosenPage extends StatefulWidget {
  const DosenPage({super.key});

  @override
  State<DosenPage> createState() => _DosenPageState();
}

class _DosenPageState extends State<DosenPage> {
  List<Datum> data = [];

  //  @override
  // void initState() {
  //   super.initState();
  //   fetchData();
  // }

  // fetchData() async {
  //   final apiResponse = await ListDosenProvider().getDosen() ??;
  //   setState(() {
  //     data = (apiResponse.data!);
  //   });
  // }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: PreferredSize(
        preferredSize: const Size.fromHeight(kToolbarHeight),
        child: CustomAppbar(
          title: 'Dosen',
        ),
      ),
      body: Center(
        child: FutureBuilder<List<ModelDosen>>(
          future: ListDosenProvider.getDosen(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return Expanded(
                child: ListView.builder(
                  itemCount: snapshot.data!.length,
                  itemBuilder: (context, index) {
                    return Container(
                      width: MediaQuery.of(context).size.width,
                      decoration: BoxDecoration(
                        color: Colors.white,
                        borderRadius: const BorderRadius.all(
                          Radius.circular(8),
                        ),
                        boxShadow: [
                          BoxShadow(
                            color: Colors.grey.withOpacity(0.2),
                            spreadRadius: 1,
                            blurRadius: 9,
                            offset: const Offset(
                                1, 2), // changes position of shadow
                          ),
                        ],
                      ),
                      child: Padding(
                        padding: const EdgeInsets.all(14),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                Text(
                                  data[index].name.toString(),
                                  style: bold6,
                                ),
                                Text(
                                  data[index].prodi.toString(),
                                  style: regular6,
                                ),
                                const SizedBox(
                                  height: 12,
                                ),
                                Row(
                                  children: [
                                    SizedBox(
                                      width: 94,
                                      height: 32,
                                      child: TextButton(
                                        onPressed: () {},
                                        style: TextButton.styleFrom(
                                          backgroundColor:
                                              const Color(0xffB3FFAE),
                                          shape: RoundedRectangleBorder(
                                            borderRadius:
                                                BorderRadius.circular(8),
                                          ),
                                        ),
                                        child: Text(
                                          "Email",
                                          style: boldButton1.copyWith(
                                            color: const Color(
                                              0xff379237,
                                            ),
                                          ),
                                        ),
                                      ),
                                    ),
                                    const SizedBox(
                                      width: 8,
                                    ),
                                    SizedBox(
                                      width: 94,
                                      height: 32,
                                      child: TextButton(
                                        onPressed: (() {}),
                                        style: TextButton.styleFrom(
                                          backgroundColor:
                                              const Color(0xffC5D5FF),
                                          shape: RoundedRectangleBorder(
                                            borderRadius:
                                                BorderRadius.circular(8),
                                          ),
                                        ),
                                        child: Text(
                                          "Detail",
                                          style: boldButton2.copyWith(
                                            color: primaryColor,
                                          ),
                                        ),
                                      ),
                                    ),
                                  ],
                                )
                              ],
                            ),
                            Image.asset(
                              'assets/images/user.png',
                              width: 50,
                            )
                          ],
                        ),
                      ),
                    );
                  },
                ),
              );
            } else {
              return CircularProgressIndicator(
                color: primaryColor,
              );
            }
          },
        ),
      ),
    );
  }
}

and this is the response when calling API the response is also Ok 200

enter image description here

enter image description here


Solution

  • Please replace your class with this

    class ListDosenProvider {
      static Future<List<Datum>> getDosen() async {
        String url =  Constant.baseURL;
        String token =
            await UtilSharedPreferences.getToken();
        final response = await https.get(
          Uri.parse(
            '$url/auth/mhs_siakad/dosen',
          ),
          headers: {
            'Authorization': 'Bearer $token',
          },
        );
      
        if (response.statusCode == 200) {
          final result = json.decode(response.body) as Map<String, dynamic>;
    
          ModelDosen dosen = ModelDosen.fromJson(result);
    
          List<Datum> l = dosen.data??[];
    
          return l;
        
        } else {
          throw Exception();
        }
      }
    }
    

    And update your remove ? from Datum model class is

     class ModelDosen {
      ModelDosen({
        this.status,
        this.code,
        this.data,
      });
     
      String? status;
      String? code;
      List<Datum>? data;
    

    Ui part is

     @override
      void initState() {
        super.initState();
        fabState.setFabStatus = FAB_STATUS.not_visible;
        fabState.setBottomNavStatus = NAV_STATUS.not_visible;
        getData();
      }
    
      Future<List<Datum>> getData() async {
        final result = await ListDosenProvider.getDosen();
        return result;
      }
    
    
     child: FutureBuilder<List<Datum>>(
                    future: getData(),
                    builder: (context, snapshot) {
                      if (snapshot.hasError) {
                        return Container(
                          child: const Text("error"),
                        );
                      } else if (snapshot.hasData) {
                        return Expanded(
                          child: ListView.builder(
                            itemCount: snapshot.data!.length,
                            itemBuilder: (context, index) {
                              return Container(
                                width: MediaQuery.of(context).size.width,
                                decoration: BoxDecoration(
                                  color: Colors.white,
                                  borderRadius: const BorderRadius.all(
                                    Radius.circular(8),
                                  ),
                                  boxShadow: [
                                    BoxShadow(
                                      color: Colors.grey.withOpacity(0.2),
                                      spreadRadius: 1,
                                      blurRadius: 9,
                                      offset: const Offset(
                                          1, 2), // changes position of shadow
                                    ),
                                  ],
                                ),
                                child: Padding(
                                  padding: const EdgeInsets.all(14),
                                  child: Row(
                                    mainAxisAlignment:
                                        MainAxisAlignment.spaceBetween,
                                    children: [
                                      Column(
                                        crossAxisAlignment:
                                            CrossAxisAlignment.start,
                                        children: [
                                          Text(
                                            snapshot.data![index].name.toString(),
                                          ),
                                          Text(
                                            snapshot.data![index].prodi.toString(),
                                          ),
                                          const SizedBox(
                                            height: 12,
                                          ),
                                          Row(
                                            children: [
                                              SizedBox(
                                                width: 94,
                                                height: 32,
                                                child: TextButton(
                                                  onPressed: () {},
                                                  style: TextButton.styleFrom(
                                                    backgroundColor:
                                                        const Color(0xffB3FFAE),
                                                    shape: RoundedRectangleBorder(
                                                      borderRadius:
                                                          BorderRadius.circular(8),
                                                    ),
                                                  ),
                                                  child: const Text(
                                                    "Email",
                                                  ),
                                                ),
                                              ),
                                              const SizedBox(
                                                width: 8,
                                              ),
                                              SizedBox(
                                                width: 94,
                                                height: 32,
                                                child: TextButton(
                                                  onPressed: (() {}),
                                                  style: TextButton.styleFrom(
                                                    backgroundColor:
                                                        const Color(0xffC5D5FF),
                                                    shape: RoundedRectangleBorder(
                                                      borderRadius:
                                                          BorderRadius.circular(8),
                                                    ),
                                                  ),
                                                  child: const Text(
                                                    "Detail",
                                                  ),
                                                ),
                                              ),
                                            ],
                                          )
                                        ],
                                      ),
                                      Image.asset(
                                        'assets/images/user.png',
                                        width: 50,
                                      )
                                    ],
                                  ),
                                ),
                              );
                            },
                          ),
                        );
                      } else {
                        return const CircularProgressIndicator(
                          color: Colors.pink,
                        );
                      }
                    },
                  ),
               
    

    output