Dynamic Dropdowns in Flutter: Fetching Data with API Calls
In Flutter, dropdown widgets are essential for providing users with a selection of options. But what if these options aren't statically defined within your code? What if you need to fetch them dynamically from an API? This is where the power of combining dropdowns with API calls shines.
This article will guide you through building a dynamic dropdown in Flutter, showcasing how to fetch data from an API and populate your dropdown with real-time information.
Scenario:
Imagine you're building an app that allows users to select a city from a dropdown menu. Instead of hardcoding the city list, you want to fetch them from a public API like OpenWeatherMap.
Original Code (Without API Integration):
import 'package:flutter/material.dart';
class CitySelection extends StatefulWidget {
@override
_CitySelectionState createState() => _CitySelectionState();
}
class _CitySelectionState extends State<CitySelection> {
String? _selectedCity;
List<String> cities = ["London", "Paris", "New York"];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("City Selection"),
),
body: Center(
child: DropdownButton<String>(
value: _selectedCity,
hint: Text('Select a City'),
items: cities.map((String city) {
return DropdownMenuItem<String>(
value: city,
child: Text(city),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
_selectedCity = newValue;
});
},
),
),
);
}
}
This code displays a dropdown with three hardcoded cities. Let's transform this into a dynamic dropdown by fetching cities from an API.
Dynamic Dropdown with API Call:
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class CitySelection extends StatefulWidget {
@override
_CitySelectionState createState() => _CitySelectionState();
}
class _CitySelectionState extends State<CitySelection> {
String? _selectedCity;
List<String> cities = [];
Future<void> fetchCities() async {
final response = await http.get(Uri.parse("https://api.openweathermap.org/data/2.5/find?q=London,Paris,NewYork&appid=YOUR_API_KEY"));
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
setState(() {
cities = data['list'].map((city) => city['name']).toList();
});
} else {
throw Exception("Failed to load cities");
}
}
@override
void initState() {
super.initState();
fetchCities();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("City Selection"),
),
body: Center(
child: DropdownButton<String>(
value: _selectedCity,
hint: Text('Select a City'),
items: cities.map((String city) {
return DropdownMenuItem<String>(
value: city,
child: Text(city),
);
}).toList(),
onChanged: (String? newValue) {
setState(() {
_selectedCity = newValue;
});
},
),
),
);
}
}
Explanation:
- Import Libraries: Include
http
anddart:convert
to handle API calls and JSON parsing. fetchCities()
Method: This function performs the API request:- Uses
http.get
to fetch data from OpenWeatherMap. - Replaces
YOUR_API_KEY
with your actual API key. - Parses the JSON response using
jsonDecode
. - Updates the
cities
list in the state usingsetState
.
- Uses
initState()
Method: CallsfetchCities()
when the widget is initialized.- Dropdown Construction: The dropdown is constructed with the
cities
list, which is now dynamically populated from the API.
Key Considerations:
- Error Handling: Implement robust error handling in the
fetchCities()
method to display appropriate messages to the user if the API call fails. - API Key Management: Securely store your API key and avoid hardcoding it in your code. Use environment variables or secure storage mechanisms.
- Data Transformation: The API response may not directly match your dropdown requirements. You might need to transform the data before displaying it in the dropdown.
- Caching: Consider caching the API response to improve performance for subsequent dropdown displays.
Additional Value:
- This approach can be extended to fetch data from any API, making your dropdown dynamic and responsive.
- You can further enhance the user experience by adding a loading indicator while the API call is in progress.
Conclusion:
By combining dropdowns with API calls, you can create dynamic user interfaces that are flexible and data-driven. This approach allows you to build powerful applications that leverage real-time information, making them more engaging and informative for your users.
References: