New to flutter and dart, struggling to populate this dropdown from an api that returns an object and within the object there is a data array of objects. Looks like:
{
"data": [
{
"Country_str_code": "AL",
"Region_str_code": "Eur",
"Country_str_name": "Albania"
},
{
"Country_str_code": "DZ",
"Region_str_code": "Afr",
"Country_str_name": "Algeria"
},
]
}
Below is the code for my widget. I will like just show the country name but not sure if I will need the country code in the dropdown so save it on submission. I cannot even get this to show. I'm getting this error:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'register.dart';
Future<List<Country>> fetchCountries() async {
final response = await http.get(Uri.https('localhost/msd', '/api/countries'));
final responseJson = json.decode(response.body);
print(responseJson['data']);
if (response.statusCode == 200) {
return (responseJson['data'] as List<Country>)
.map((country) => country);
} else {
throw Exception('Failed to load countries');
}
}
class Country {
final String countryCode;
final String countryName;
Country({@required this.countryCode, @required this.countryName});
factory Country.fromJson(Map<String, dynamic> json) {
var countrNameFromJson = json['Country_str_name'];
var countrCodeFromJson = json['Country_str_code'];
String castedCountryName = countrNameFromJson.cast<String>();
String castedCountryCode = countrCodeFromJson.cast<String>();
return Country(
countryCode: castedCountryCode,
countryName: castedCountryName
);
}
}
class Location extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return LocationState();
}
}
class LocationState extends State<Location> {
Future<List<Country>> futureCountry;
Map<String, dynamic> _selected = {'countryCode': '', 'countryName':'Select Country'};
@override
void initState() {
super.initState();
futureCountry = fetchCountries();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Registrate'),
backgroundColor: Colors.blue[600],
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Center(
child: FutureBuilder<List<Country>>(
future: futureCountry,
builder: (context, snapshot) {
if (snapshot.hasData) {
print (snapshot.data);
return DropdownButton(
value: _selected,
icon: Icon(Icons.arrow_drop_down),
iconSize: 30,
elevation: 16,
style: TextStyle(color: Colors.black),
onChanged: (newValue) {
setState(() {
_selected = newValue;
});
},
items: snapshot.data
.map<DropdownMenuItem<String>>((Country value) {
return DropdownMenuItem<String>(
value: value.countryCode,
child: Text(value.countryName),
);
}).toList(),
);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return CircularProgressIndicator();
},
),
),
SizedBox(
width: double.maxFinite,
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Register())
);
},
child: Text('Continue'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.red[900]),
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
)
),
),
],
),
);
}
}
Currently getting this error:
type 'List<dynamic> is not a subtype of type 'List<Country>' in type cast
Can someone please guide me, as the error says clearly its an issue with the types but I'm not sure how solve this.