'Searchable Dropdown with Flutter Rest Api Problem

I am Calling an Api to filter Countries list with Region. Whenever I Select the region it filter and show all countries of the selected region. I'm using searchable_dropdown package to filter.

My Searchable Dropdown Filter is Working Fine But Not getting All Data Without Selecting from Dropdown.

What i want :- i want to show all Available data from api when app runs or when no region is selected from dropdown as in Screenshot 1.

My Codes are Below

Main.dart

import 'package:flutter/material.dart';
import 'package:searchable_dropdown_flutter/searchable_dropdown1.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: SearchableDropdownApp(),
    );
  }
}

searchable_dropdown.dart

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

class SearchableDropdownApp extends StatefulWidget {
  @override
  _AppState createState() => _AppState();
}

class _AppState extends State<SearchableDropdownApp> {
  Map<String, String> selectedValueMap = Map();

  // ignore: deprecated_member_use
  List filteredData = List();

  // ignore: deprecated_member_use
  List filteredDataAll = List();
  // ignore: deprecated_member_use
  List alldata = List();

  @override
  void initState() {
    selectedValueMap["server"] = null;
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          automaticallyImplyLeading: false,
          title: const Text('Searchable Dropdown Example App'),
        ),
        body: FutureBuilder(
          // get data from server and return a list of mapped 'name' fields
          future:
              getServerData(), //sets getServerData method as the expected Future
          // ignore: missing_return
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              // ignore: deprecated_member_use
              List<String> countries = new List();
              for (int i = 0; i < snapshot.data.length; i++) {
                if (!countries.contains(snapshot.data[i]['region']))
                  countries.add(snapshot.data[i]['region']);
              }

              alldata = snapshot.data;
              //checks if response returned valid data
              // use mapped 'name' fields for providing options and store selected value to the key "server"
              return getSearchableDropdown(countries, "server", alldata);
            } else if (snapshot.hasError) {
              //checks if the response threw error
              return Text("${snapshot.error}");
            }
            return Center(child: CircularProgressIndicator());
          },
        ),
      ),
    );
  }

  Widget getSearchableDropdown(List<String> listData, mapKey, alldata) {
    List<DropdownMenuItem> items = [];
    for (int i = 0; i < listData.length; i++) {
      items.add(new DropdownMenuItem(
        child: new Text(
          listData[i],
        ),
        value: listData[i],
      ));
    }
    return Scaffold(
      body: Column(
        children: [
          SearchableDropdown(
            isExpanded: true,
            style: TextStyle(color: Colors.red),
            items: items,
            value: selectedValueMap[mapKey],
            isCaseSensitiveSearch: false,
            hint: new Text('Select Country'),
            searchHint: new Text(
              'Select Country',
              style: new TextStyle(fontSize: 20),
            ),
            onChanged: (value) {
              setState(() {
                selectedValueMap[mapKey] = value;
                print('selectedValueMap[mapKey]');
                print(selectedValueMap[mapKey]);

                // ignore: deprecated_member_use
                filteredData = new List();
                for (int i = 0; i < alldata.length; i++) {
                  if (alldata[i]['region'] == selectedValueMap[mapKey])
                    filteredData.add(alldata[i]);
                }

                filteredDataAll = filteredData.toList();
                print('filteredDataAll ka data');
              });
            },
          ),
          Text(selectedValueMap[mapKey].toString()),
          Text('data'),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(8.0),
              child: ListView.builder(
                  scrollDirection: Axis.vertical,
                  shrinkWrap: true,
                  itemCount: filteredDataAll.length,
                  itemBuilder: (context, index) {
                    return SingleChildScrollView(
                      child: Card(
                          child: Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Column(
                          children: [
                            Text(filteredDataAll[index].toString()),
                          ],
                        ),
                      )),
                    );
                  }),
            ),
          ),
        ],
      ),
    );
  }

  Future<List> getServerData() async {
    String url =
        'https://restcountries.eu/rest/v2/all?fields=name;capital;alpha3Code;region;population;';
    final response =
        await http.get(url, headers: {"Accept": "application/json"});

    if (response.statusCode == 200) {
      List<dynamic> responseBody = json.decode(response.body);
      return responseBody;
    } else {
      print("error from server : $response");
      throw Exception('Failed to load post');
    }
  }
}

SecreenShots

When App Run for First Time SecreenShots 1

After Selecting from Filter SecreenShots 2



Solution 1:[1]

try this its works fine for me...

FutureBuilder<List<AllAccountModel>>(
                future: accountData,
                builder: (context, snapshot){
              if(snapshot.hasData){
                List<String> dropDown=List.filled(snapshot.data!.length, '',growable: true);
                print(snapshot.data!.length);
                for(int i=0;i<=snapshot.data!.length-1;i++){
                  dropDown[i]=snapshot.data![i].accountName+"\n"+snapshot.data![i].phoneNo;
                }
                return   DropdownSearch<String>(
                  mode: Mode.MENU,
                  items: dropDown,
                  showSearchBox: true,
                  label: "Account Name",
                  onChanged: print,
                );
              }else{
                DropdownSearch<String>(
                  mode: Mode.MENU,
                  items: [snapshot.error.toString()],
                  showSearchBox: true,
                  label: "Account Name",
                  onChanged: print,
                );
              }
              return
                 const Padding(
                    padding: EdgeInsets.all(8.0),
                    child: Center(
                      child:
                      CircularProgressIndicator(),
                    ),
                  );

            })

call Api in initState

@override void initState()  {
// TODO: implement initState
super.initState();
accountData = allAccounts();}

my Api Function

Future<List<AllAccountModel>> allAccounts() async {
return HttpService().getAllAccounts();}

End Result

End Result

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ahmed Javed