// ignore_for_file: prefer_const_constructors, avoid_unnecessary_containers, prefer_const_literals_to_create_immutables, import_of_legacy_library_into_null_safe, non_constant_identifier_names, unused_field, avoid_print
import 'dart:convert';
import 'package:dropdownfield/dropdownfield.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FoodWidget extends StatefulWidget {
const FoodWidget({Key? key}) : super(key: key);
@override
_FoodWidgetState createState() => _FoodWidgetState();
}
class _FoodWidgetState extends State<FoodWidget> {
@override
void initState() {
fetchFood();
super.initState();
}
String? food_id;
List food = [];
Future<void> fetchFood() async {
final String response =
await rootBundle.loadString('assets/list_food.json');
final data = await json.decode(response);
print(data);
setState(() {
food = data["food"];
});
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
DropDownField(
onValueChanged: (dynamic value) {
food_id = value;
},
value: food_id,
required: false,
labelText: 'Search food',
items: food,
),
]),
);
}
}
and this is the JSON file. I want to get only names in DropDownField but I can't do it. At the setState function, I really don't know how to put it.
{
"food": [
{
"id": 1,
"name": "coca-cola",
"calories": 120
},
{
"id": 2,
"name": "egg",
"calories": 80
},
{
"id": 3,
"name": "rice",
"calories": 100
}
]
}
I tried to print(data) to test the output. It's all coming out of the domain name, but I want to use that inside. And I really don't know how to do it.
PS. I really will appreciate with answers and suggestions.
CodePudding user response:
you would just need to map the data to get only its name :
Future<void> fetchFood() async {
final String response =
await rootBundle.loadString('assets/list_food.json');
final data = await json.decode(response);
print(data);
setState(() {
food = data["food"].map((e)=>e['name']).toList();
});
}
There after getting the list of foods, you map each item to get only the food name, which is what you need.
As a sidenote
I would recommend that in the future you create a model like :
class Food {
Food({
this.id,
this.name,
this.calories,
});
int id;
String name;
int calories;
factory Food.fromJson(Map<String, dynamic> json) => Food(
id: json["id"],
name: json["name"],
calories: json["calories"],
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"calories": calories,
};
}
So you have a strongly typed List<Food> food
and you could access parameters in a type safe matter.
CodePudding user response:
You need to Generate Food class
class Food {
String? id;
String? name;
String? calories;
Food({
this.id,
this.name,
this.calories,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'calories': calories,
};
}
factory Food.fromMap(Map<String, dynamic> map) {
return Food(
id: map['id'],
name: map['name'],
calories: map['calories'],
);
}
String toJson() => json.encode(toMap());
factory Food.fromJson(String source) => Food.fromMap(json.decode(source));
}
Full Code here:
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class FoodWidget extends StatefulWidget {
const FoodWidget({Key? key}) : super(key: key);
@override
_FoodWidgetState createState() => _FoodWidgetState();
}
class _FoodWidgetState extends State<FoodWidget> {
@override
void initState() {
fetchFood();
super.initState();
}
String? food_id;
Food? selected_food ;
List<Food> food = [];
Future<void> fetchFood() async {
final String response =
await rootBundle.loadString('assets/list_food.json');
final data = await json.decode(response) as List;
print(data);
setState(() {
food = data.map((e) => Food.fromJson(e)).toList();
});
}
@override
Widget build(BuildContext context) {
return Container(
padding:const EdgeInsets.all(15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
DropdownButton<Food>(
focusColor: Colors.white,
value: selected_food,
//elevation: 5,
style: const TextStyle(color: Colors.white),
iconEnabledColor: Colors.black,
underline: const SizedBox.shrink(),
items: food.map<DropdownMenuItem<Food>>(
(Food value) {
return DropdownMenuItem<Food>(
value: value,
child: Text(
value.name!,
style: const TextStyle(color: Colors.black),
),
);
}).toList(),
hint: const Text(
"Select Shop Category",
style: TextStyle(
color: Colors.black38,
),
),
onChanged: (Food? value) {
setState(() {
selected_food= value!;
});
},
),
]),
);
}
}
class Food {
String? id;
String? name;
String? calories;
Food({
this.id,
this.name,
this.calories,
});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'calories': calories,
};
}
factory Food.fromMap(Map<String, dynamic> map) {
return Food(
id: map['id'],
name: map['name'],
calories: map['calories'],
);
}
String toJson() => json.encode(toMap());
factory Food.fromJson(String source) =>
Food.fromMap(json.decode(source));
}