Good day. Please I am have a challenge on how to change my hardcoded data to dynamic from the api. The response to the API returns success but populating the card carousel is the challenge I am having. I keep on getting error "type 'List' is not a subtype of type 'List<Map<String, String>>'"'
This my Api request:
SharedPreferences _prefs;
void getCategories() async {
try {
_prefs = await SharedPreferences.getInstance();
var _categoryService = CategoryService();
var result =
await _categoryService.getCategories(_prefs.getString('token'));
var categories = json.decode(result.body);
print('categories');
print(categories);
List<Map<String, String>> foodCategories = categories;
} catch (e) {
throw Exception();
}
}
This is my list variable with hard coded data:
final List<Map<String, String>> foodCategories = [
{
'name': 'Rice Planting',
'image': 'images/Icon-001.png',
},
{
'name': 'Harvesting',
'image': 'images/Icon-002.png',
},
{
'name': 'Machineries',
'image': 'images/Icon-003.png',
},
{
'name': 'Rice Products',
'image': 'images/Icon-004.png',
}
];
And this is my screen:
Container(
height: 105,
margin: const EdgeInsets.only(
top: 20.0,
bottom: 25.0,
),
child: ListView.builder(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.only(
left: 20.0,
),
itemCount: this.foodOptions.length,
itemBuilder: (context, index) {
Map<String, String> option = this.foodOptions[index];
return Container(
margin: const EdgeInsets.only(right: 35.0),
child: Column(
children: <Widget>[
Container(
width: 70,
height: 70,
margin: const EdgeInsets.only(bottom: 10.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
image: DecorationImage(
image: AssetImage(
option['image'],
),
),
boxShadow: [
BoxShadow(
blurRadius: 10.0,
color: Colors.grey[300],
offset: Offset(6.0, 6.0),
)
],
),
),
Text(
option['name'],
style: TextStyle(fontSize: 17.0),
),
],
),
);
}),
),
My basic challenge is how to switch this hardcoded data of **foodCategories ** to
var categories = json.decode(result.body); which is from the API. any suggestion I will highly appreciate. The Api returns a json with image and category name
this is the UI picture
CodePudding user response:
Declare this List in your screen widget:
final List<Map<String, String>> foodCategories = [
{
'name': 'Rice Planting',
'image': 'images/Icon-001.png',
},
{
'name': 'Harvesting',
'image': 'images/Icon-002.png',
},
{
'name': 'Machineries',
'image': 'images/Icon-003.png',
},
{
'name': 'Rice Products',
'image': 'images/Icon-004.png',
}
];
Add this method to your screen widget:
void getCategories() async {
try {
_prefs = await SharedPreferences.getInstance();
var _categoryService = CategoryService();
var result =
await _categoryService.getCategories(_prefs.getString('token'));
var categories = json.decode(result.body);
print('categories');
print(categories);
setState(() {
foodCategories = categories;
});
} catch (e) {
throw Exception();
}
}
and call the method in initState:
@override
void initState() {
super.initState();
getCategories();
}
CodePudding user response:
You can use a state management tool for this use case, like Provider, on flutter.dev there is a nice explanation on how to use it Simple app state management.
Basically you wrap the api call inside a provider class and every time data comes from the api it notify the consumers that are using the provider.