Issue
I have a list of lists in JSON format like the following. I need to convert these lists into DropDownMenu items in Flutter. To do that,
- Read the data from the JSON file
- Convert the data to an available class format(FormContent class)
- Create a Future that returns a list of FormContent.
- Read the data inside the FutureBuilder
- Convert the list of FormContent into a List of Strings that DropDownMenu could accept
At the end where I print the first item of the items
, I get Instance of 'FormContent'
as a result of this execution(I marked it in the FutureBuilder widget, below). What I was expecting is the list of "stajTuru"
in the JSON file.
["Ortopedi", "Kardiyoloji","Dermatoloji", "Pediatri"]
Since there is a nested list format. I tried to execute print(items[0][0].toString());
to get the first item's content. However, I get an error like this
Class 'FormContent' has no instance method '[]'.Receiver: Instance of 'FormContent' Tried calling: [](0)
To sum up, I need to convert these JSON contents to an individual List<String>
. Like what I was expecting above.
JSON File
[
{
"stajTuru": [ "Ortopedi", "Kardiyoloji","Dermatoloji", "Pediatri"],
"cinsiyet": ["Erkek","Kadın", "Diğer"],
"etkilesimTuru": [ "Gözlem", "Yardımla yapma","Yardımsız yapma","Sanal olgu"],
"kapsam": [ "Öykü", "Fizik Bakı", "Tanısal akıl Yürütme", "Teropötik akıl yürütme"],
"ortam": ["Poliklinik","Servis","Acil","Ameliyathane","Dış Kurum"],
"doktor": [ "Esra Demir","Mehmet Uçar","Kemal Yurdakul","Fehmi Öztürk","Mehmet Öz"]
}
]
FormContent class
This is my class where I keep each of those lists
class FormContent{
late List<dynamic> _cinsiyetItems;
late List<dynamic> _stajTuruItems;
late List<dynamic> _etkilesimTuruItems;
late List<dynamic> _kapsamItems;
late List<dynamic> _ortamItems;
late List<dynamic> _doktorItems;
FormContent.fromJson(Map<String,dynamic> jsonFile){
_cinsiyetItems=jsonFile['cinsiyet']!.toList();
_stajTuruItems=jsonFile['stajTuru']!.toList();
_etkilesimTuruItems=jsonFile['etkilesimTuru']!.toList();
_kapsamItems=jsonFile['kapsam']!.toList();
_ortamItems=jsonFile['ortam']!.toList();
_doktorItems=jsonFile['doktor']!.toList();
}
}
Method to read JSON
This is my method where I convert the JSON data into a list
Future<List<dynamic>> readJsonData() async{
final jsonData = await rootBundle.rootBundle.loadString('assets/json/formdata.json');
print(jsonData.toString());
final list = json.decode(jsonData) as List<dynamic>;
print("======================================");
print(list.toString());
var result =list.map((e) => FormContent.fromJson(e)).toList();
print("------------------------------------------");
print(result.toString());
return result;
}
FutureBuilder method
Lastly, this is my FutureBuilder to execute the data
FutureBuilder(
future:readJsonData() ,
builder: (context,snapshot){
if(snapshot.hasError){
return Text(snapshot.error.toString());
}else if(snapshot.hasData){
var items =snapshot.data as List<dynamic>;
print("--------------***********************************");
print(items[0].toString()); // <--- HERE
return
ListView(
children: [
myTextFieldRow("Kayıt No: ", 10,_formData.setKayitNo),
myDropDownContainer(_valueStajTuru,_stajTuruItems,
hintTextStajTuru, onChangedStajTuru),
// myDropDownContainer(_valueDoktor, _doktorItems, hintTextDoktor, onChangedDoktor),
myTextFieldRow("Hastanın Yaşı:", 3, _formData.setYas),
// myDropDownContainer(_valueCinsiyet, _cinsiyetItems, hintTextCinsiyet, onChangedCinsiyet),
myTextFieldRow("Şikayet:", 10,_formData.setSikayet),
myTextFieldRow("Ayırıcı Tanı:", 50,_formData.setAyiriciTani),
myTextFieldRow("Kesin Tanı:", 50,_formData.setKesinTani),
myTextFieldRow("Tedavi Yöntemi:", 100,_formData.setTedaviYontemi),
// myDropDownContainer(_valueEtkilesim, _etkilesimTuruItems, hintTextEtkilesim, onChangedEtkilesim),
// myDropDownContainer(_valueKapsam, _kapsamItems, hintTextKapsam, onChangedKapsam),
// myDropDownContainer(_valueOrtam, _ortamItems, hintTextOrtam, onChangedOrtam),
const SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
SizedBox(
width: 150,
height: 50,
child: TextButton(
onPressed: () {
setState(() {
_formAdd.addNewFormToList(_formData);
_formData=FormData();
Navigator.push(context, MaterialPageRoute(builder: (context)=> StudentProfile(formAdd: _formAdd)));
});
},
child: Text(
"GÖNDER",
style: kTextStyle.copyWith(fontSize: 20),
),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(
const Color(0xff4F4DBB),
),
),
),
),
],
),
],
);
} else{
return const Center(child:CircularProgressIndicator(),);
}
}
)),
Solution
First of all your FormContent
class needs to be reworked in some way. Everything in the class is currently private which doesn't give you any way to get at the data contained within the class. Also you could be more specific by giving the lists type List<String>
rather than List<dynamic>
, and there is no need to make the properties late
either. This is my suggested rewrite of the class:
class FormContent {
List<String> cinsiyetItems;
List<String> stajTuruItems;
List<String> etkilesimTuruItems;
List<String> kapsamItems;
List<String> ortamItems;
List<String> doktorItems;
FormContent.fromJson(Map<String, dynamic> jsonFile)
: cinsiyetItems = [...?jsonFile['cinsiyet']],
stajTuruItems = [...?jsonFile['stajTuru']],
etkilesimTuruItems = [...?jsonFile['etkilesimTuru']],
kapsamItems = [...?jsonFile['kapsam']],
ortamItems = [...?jsonFile['ortam']],
doktorItems = [...?jsonFile['doktor']];
}
As for your readJsonData
function, you should be more specific by specifying the type as Future<List<FormContent>>
rather than Future<List<dynamic>>
. I would rewrite as follows:
Future<List<FormContent>> readJsonData() async {
final jsonData = await rootBundle.rootBundle.loadString('assets/json/formdata.json');
return [
for (final e in json.decode(jsonData)) FormContent.fromJson(e),
];
}
As for this issue:
At the end where I print the first item of the items, I get Instance of 'FormContent' as a result of this execution(I marked it in the FutureBuilder widget, below). What I was expecting is the list of "stajTuru" in the JSON file.
You are simply printing out the first element you got from readJsonData
which is an instance of your FormContent
class. You can do print(items[0].stajTuruItems);
to see the stajTuru
list printed out.
Answered By - mmcdon20
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.