skip to Main Content

how do I call the API data into the dropdown I have done several times, when I used local data in the form of a String list I managed to call the data, but when I tried to call from the API data the result was empty and the results in the dropdown did not display any data

 Future<List<Agama>> getAgama() 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 result =
          json.decode(response.body)['nm_agama'] as Map<String, dynamic>;
      UserBiodata agama = UserBiodata.fromJson(result);
      List<Agama> l = agama.data ?? [];
      return l;
    } else {
      throw Exception();
    }
  }

in widget

 List<Agama>? religion = [];



 @override
  void initState() {
    super.initState();
    BiodataProvider().getAgama();
  }

  var dropdownAgama;
...
     FutureBuilder(
                future: BiodataProvider().getBiodata(),
                builder: (context, snapshot) {
                  if (snapshot.hasData) {
                    print(' ini Agama $religion');
                    return Column(
                      children: [
                        Text(
                          snapshot.data!.data!.name.toString(),
                          style: bold5,
                        ),
                        DropdownButton(
                          hint: const Text('Religion'),
                          items: religion!.map((item) {
                            return DropdownMenuItem(
                              value: item.nmAgama.toString(),
                              child: Text(item.idAgama.toString()),
                            );
                          }).toList(),
                          onChanged: (newVal) {
                            setState(() {
                              dropdownAgama = newVal;
                            });
                          },
                          value: dropdownAgama,
                        ),
                      ],
                    );
                  } else {
                    return const Text('No Data');
                  }
                }),
...

this is the model i am using which is converted from API

class Agama {
  String? id;
  String? idAgama;
  String? nmAgama;
  String? createdAt;
  String? updatedAt;
  dynamic createdBy;
  dynamic updatedBy;

  Agama(
      {this.id,
      this.idAgama,
      this.nmAgama,
      this.createdAt,
      this.updatedAt,
      this.createdBy,
      this.updatedBy});

  Agama.fromJson(Map<String, dynamic> json) {
    id = json['id'];
    idAgama = json['id_agama'];
    nmAgama = json['nm_agama'];
    createdAt = json['created_at'];
    updatedAt = json['updated_at'];
    createdBy = json['created_by'];
    updatedBy = json['updated_by'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = <String, dynamic>{};
    data['id'] = id;
    data['id_agama'] = idAgama;
    data['nm_agama'] = nmAgama;
    data['created_at'] = createdAt;
    data['updated_at'] = updatedAt;
    data['created_by'] = createdBy;
    data['updated_by'] = updatedBy;
    return data;
  }
}

enter image description here

2

Answers


  1. it looks like you are not assigning your api data to the

    List<Agama>? religion;
    

    you can solve this by either mapping your snapshot data directly:

     @override
      void initState() {
        super.initState();
        BiodataProvider().getAgama();
      }
    
      var dropdownAgama;
    ...
         FutureBuilder(
                    future: BiodataProvider().getBiodata(),
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        print(' ini Agama $religion');
                        return Column(
                          children: [
                            Text(
                              snapshot.data!.data!.name.toString(),
                              style: bold5,
                            ),
                            DropdownButton(
                              hint: const Text('Religion'),
                              items:  snapshot.data!.data!.map((item) {
                                return DropdownMenuItem(
                                  value: item.nmAgama.toString(),
                                  child: Text(item.idAgama.toString()),
                                );
                              }).toList(),
                              onChanged: (newVal) {
                                setState(() {
                                  dropdownAgama = newVal;
                                });
                              },
                              value: dropdownAgama,
                            ),
                          ],
                        );
                      } else {
                        return const Text('No Data');
                      }
                    }),
    

    or

    by assigning the snapshot data to your list:

        List<Agama>? religion = [];
        
        
        
         @override
          void initState() {
            super.initState();
            BiodataProvider().getAgama();
          }
        
          var dropdownAgama;
        ...
             FutureBuilder(
                        future: BiodataProvider().getBiodata(),
                        builder: (context, snapshot) {
                          if (snapshot.hasData) {
            WidgetsBinding.instance.addPostFrameCallback((_) {
    setState((){
    religion = snapshot.data!.data;
    })
             
            });
                            print(' ini Agama $religion');
                            return Column(
                              children: [
                                Text(
                                  snapshot.data!.data!.name.toString(),
                                  style: bold5,
                                ),
                                DropdownButton(
                                  hint: const Text('Religion'),
                                  items: religion!.map((item) {
                                    return DropdownMenuItem(
                                      value: item.nmAgama.toString(),
                                      child: Text(item.idAgama.toString()),
                                    );
                                  }).toList(),
                                  onChanged: (newVal) {
                                    setState(() {
                                      dropdownAgama = newVal;
                                    });
                                  },
                                  value: dropdownAgama,
                                ),
                              ],
                            );
                          } else {
                            return const Text('No Data');
                          }
                        }),
    

    hope this helps!

    Login or Signup to reply.
  2. Solution

    • In Controller Class,
      • Initialize your Future Method as your Model : Future<List<LeaveModel>> getLeaves(){}
      • create a List of Obj for Custom Class like this :
        List<LeaveModel> leaveTypeObjList = [];
      • After fetching data from API add the datas in obj list via Object

    type :LeaveModel leaveTypeObj = LeaveModel(leaveTypeResponseList[i]["LEAVE_TYPE_EN"]);

    • And in loop add it to your obj list: leaveTypeObjList.add(leaveTypeObj);

    ** In widget class at AsyncSnapshot use your List of Generics like this :
    AsyncSnapshot<List<LeaveModel>>.

    Demo Code

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:http/http.dart' as http;
    
    void main(List<String> args) {
      runApp(MyHome());
    }
    
    class MyHome extends StatelessWidget {
      const MyHome({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: MyApp(),
        );
      }
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({super.key});
    
      @override
      State<MyApp> createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      List<String> leaveTypeList = [];
      int currentLeaveType = 0;
      String? value;
      String? selectedLeaveType;
      late Future<List<LeaveModel>> futureLeaves;
    
      @override
      void initState() {
        super.initState();
        futureLeaves = FoodTypeController().getLeaves();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Container(
            height: double.infinity,
            width: double.infinity,
            child: Row(
              children: [
                Text(
                  "Leave Type =   ",
                  style: TextStyle(fontSize: 24.0),
                ),
                FutureBuilder(
                    future: futureLeaves,
                    builder: ((BuildContext context,
                        AsyncSnapshot<List<LeaveModel>> snapshot) {
                      if (snapshot.hasData) {
                        leaveTypeList = [];
                        List<LeaveModel>? LeaveTypes = snapshot.data;
    
                        for (int i = 0; i < LeaveTypes!.length; i++) {
                          leaveTypeList.add(LeaveTypes[i].leaveTypes!);
                        }
    
                        return SizedBox(
                          width: 200,
                          height: 50,
                          child: Container(
                            padding: EdgeInsets.only(left: 2.0, right: 4.0),
                            decoration: BoxDecoration(
                                borderRadius: BorderRadius.circular(20),
                                border: Border.all(color: Colors.black, width: 1)),
                            child: DropdownButtonHideUnderline(
                              child: DropdownButton<String>(
                                borderRadius: BorderRadius.circular(12),
                                value: currentLeaveType == null? null: leaveTypeList[currentLeaveType],
                                icon: Icon(Icons.arrow_drop_down_rounded),
                                items: leaveTypeList.map(buildMenuItem).toList(),
                                onChanged: (value) => setState(() {
                                  currentLeaveType = leaveTypeList.indexOf(value.toString());
                                  this.value = value;
    
                                  selectedLeaveType = this.value;
                                }),
                              ),
                            ),
                          ),
                        );
                      } else if (snapshot.hasError) {
                        return const Text("Error to load Snapshot");
                      } else {
                        return const CircularProgressIndicator();
                      }
                    })),
              ],
            ),
          ),
        );
      }
    
      DropdownMenuItem<String> buildMenuItem(String item) => DropdownMenuItem(
            value: item,
            child: Text(
              item.toString(),
              style: TextStyle(fontWeight: FontWeight.w400, fontSize: 24.0),
            ),
          );
    }
    
    class LeaveModel {
      String? leaveTypes;
      LeaveModel(this.leaveTypes);
    }
    
    class FoodTypeController {
      Future<List<LeaveModel>> getLeaves() async {
        List<LeaveModel> leaveTypeObjList = [];
    
        String url = "";
    
        http.Response response =
            await http.post(Uri.parse(url), body: {"user": "", "pass": ""});
    
        if (response.statusCode == 200) {
          List leaveTypeResponseList = jsonDecode(response.body);
    
          for (int i = 0; i < leaveTypeResponseList.length; i++) {
            LeaveModel leaveTypeObj =
                LeaveModel(leaveTypeResponseList[i]["LEAVE_TYPE"]);
            leaveTypeObjList.add(leaveTypeObj);
          }
          return leaveTypeObjList;
        } else {
          throw Exception("Error to load data in Leave Controller");
        }
      }
    }
    
    

    Response

    di

    Visual

    ezgif-4-42fcba32ba

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search