'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
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 |

