skip to Main Content

I am working on e commerce application in that app I want to set dropdown data from api. I am fresher in flutter so I need to help

Dropdown Code

DropdownButton<String>(
                                value: _selectedOption,
                                items:_options.map<DropdownMenuItem<String>>(
                                        (String value) {
                                  return DropdownMenuItem<String>(
                                    value: value,
                                    child: Text(value),
                                  );
                                }).toList(),
                                onChanged: (value) {
                                          setState(() {
                                       _selectedOption = value!;
                                            });
                                },
 
                             ),
@override
 void initState() {
   ProductDetailsNet.fetchProductDetails(widget.utils.id.toString()).then(
           (value) {
         List<String> fetchedOptions = value.cast<String>();

         List<String> options = [];
         for (String option in fetchedOptions) {
           String concatenatedOption = option;
           options.add(concatenatedOption);         }
         setState(() {
           _options = options;
           _selectedOption = _options.isNotEmpty ? _options[0] : '';
         });
       }
   );
 }

my api calling code:

class ProductDetailsNet{
  static List<ProductDetailsUtils> parseService (String responseBody){
    var list=json.decode(responseBody) as List<dynamic>;
    List<ProductDetailsUtils> serviceList=list.map((e) => ProductDetailsUtils.fromJson(e)).toList();
    return serviceList;
  }
 static Future<List<ProductDetailsUtils>> fetchProductDetails(String pid ) async{
    final url=Uri.parse('https://wiz-mart.com/api/prodetails.php');
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? username=prefs.getString("username");
    final queryParams = {
      'username': username,
      'pid': pid,
    };
    final newUrl = url.replace(queryParameters: queryParams);
    print(newUrl);
    try{
      final response = await http.get(newUrl);
      if (response.statusCode == 200)
      {
        final data = json.decode(response.body);
        List<String> options = [];

        String option1 = "${data['psize']} ${data['uom']}";
        String option2 = "${data['psize2']} ${data['uom2']}";
        String option3 = "${data['price3']} ${data['uom3']}";

        options.add(option1);
        options.add(option2);
        options.add(option3);
        print('Login successful!');
        print(response.body);
        return parseService(response.body);
      }else {
        print('Login failed! Status code: ${response.statusCode}');
        print('Response body: ${response.body}');

      }
    }catch (error) {
      print('Error occurred: $error');

    }
    throw Exception('Unable to retrieve product details.');



  }

when I run this code I got error Error occurred: type ‘String’ is not a subtype of type ‘int’ of ‘index’
and my data not set to the widgets. So what should I do for.

2

Answers


  1. I’ve added the whole code from my own project. Think, test, and try to customize yourself.enter image description here

    API services

    //Division API - replaice your own model instade of DistrictModel
    var divisionUrl = "$baseURL/location/division";
    
    Future<DivisionModel?> getDivition() async {
      var res = await http.get(Uri.parse(divisionUrl));
      var divitionStatusCode = res.statusCode;
      print("Divition status code $divitionStatusCode");
      if (res.statusCode == 200) {
        DivisionModel division = divisionModelFromJson(res.body);
        return division;
      }
      return null;
    }
    
    //district API 
    Future<DistrictModel?> getDistrict(String divisionId) async { 
      final uri = Uri.parse(
          '$baseURL/location/district?division_id=$divisionId');
      final response = await http.get(uri);
    
      var districtStatusCode = response.statusCode;
      print("District status code $districtStatusCode");
      if (response.statusCode == 200) {
        DistrictModel district = districtModelFromJson(response.body);
        return district;
      } else {
        return null;
      }
    }
    

    Here is how I called and implement API response in the dropdown.

    class RegisterPage extends StatefulWidget {
      const RegisterPage({super.key});
    
      @override
      State<RegisterPage> createState() => _RegisterPageState();
    }
    
    class _RegisterPageState extends State<RegisterPage> {
      List<Divition> listOfDivition =
          []; //get all the divition from api in this list
      String? selectedDivition; //get selected divition id
    
      @override
      void initState() {
        loadingDivition(); //load the divition data first
        super.initState();
      }
    
      var isLoading = true; //to check the API is loading or not
      loadingDivition() async {
        //binding with the diviton Url
        DivisionModel? divition = await getDivition();
        setState(() {
          listOfDivition = divition!.data;
          isLoading = false; //after getting the Data loading will be false
        });
      }
    
      List<District> listOfDistrict =
          []; //get all the district from api in this list
      String? selectedDistrict;
    
      loadingDistrict() async {
        DistrictModel? district = await getDistrict(selectedDivition.toString());
        setState(() {
          listOfDistrict = district!.data;
          isLoading = false;
        });
      }
    
      GlobalKey<FormState> registerFormKey = GlobalKey<FormState>();
    
      String? divitionValue = "";
      String? districtValue = "";
    
      Future<void> publicUserRegister() async {
        if (selectedDivition!.isNotEmpty && selectedDistrict!.isNotEmpty) {
          var registerData = {
            "division_id": selectedDivition,
            "district_id": selectedDistrict
          };
    
          var response = await registerUser(registerData);
    
          var body = jsonDecode(response.body);
          var responseMsg = body['message'];
          print(responseMsg);
        } else {
          print("All fields are required!");
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: const Color(0xffffffff),
          body: SingleChildScrollView(
            padding: const EdgeInsets.symmetric(horizontal: 24),
            child: Form(
              key: registerFormKey,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.end,
                children: [
                  DropdownButtonFormField(
                    hint: const Text(
                      "-- Select Divition --",
                    ),
                    value: selectedDivition,
                    onChanged: (value) {
                      selectedDistrict = null;
                      setState(() {
                        selectedDivition = value;
                        loadingDistrict();
                        isLoading = true;
                      });
                    },
                    onSaved: (value) {
                      setState(() {
                        divitionValue = value;
                      });
                    },
                    items: listOfDivition.map((e) {
                      return DropdownMenuItem(
                        value: e.id.toString(),
                        child: Text(e.nameBn),
                      );
                    }).toList(),
                  ),
                  DropdownButtonFormField(
                    hint: const Text(
                      "-- Select District --",
                    ),
                    value: selectedDistrict,
                    onChanged: (value) {
                      setState(() {
                        selectedDistrict = value;
                      });
                    },
                    onSaved: (value) {
                      setState(() {
                        districtValue = value;
                      });
                    },
                    validator: (String? value) {
                      if (value!.isEmpty) {
                        return "can't empty";
                      } else {
                        return null;
                      }
                    },
                    items: listOfDistrict.map((e) {
                      return DropdownMenuItem(
                        value: e.id.toString(),
                        child: Text(e.nameBn),
                      );
                    }).toList(),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
  2. Use Future Builder, It will take the stream and display data in your dropdown.

    Here is the link of GitHub repo where i have used Future Builder
    https://github.com/zeeshan564/News-Application/blob/API-Integration/lib/screens/home_screen/home_screen.dart

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