Problem with loading data from json in Flutter Stateful Widget - json

When loading data from json I got some problem. I think the problem is in fetching the data.
Any idea what's going on?
I'm not best Flutter developer it's more like hobby so try to be easygoing.
Here is error:
The following NoSuchMethodError was thrown building RulesCard(dirty,
dependencies: [_LocalizationsScope-[GlobalKey#806d5],
_InheritedTheme], state: _RulesCardState#471f3):
The getter 'campusRulesList' was called on null. Receiver: null Tried calling:
campusRulesList
The relevant error-causing widget was: RulesCard
file:///H:/Projekty/kampus_sggw/lib/global_widgets/side_drawer.dart:43:57
When the exception was thrown, this was the stack:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
#1 _RulesCardState.build (package:kampus_sggw/screens/map_screen/rules_card.dart:69:53)
#2 StatefulElement.build (package:flutter/src/widgets/framework.dart:4684:27)
#3 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4567:15)
#4 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4739:11) ...
════════════════════════════════════════════════════════════════════════════
E/flutter (18750): [ERROR:flutter/lib/ui/ui_dart_state.cc(186)]
Unhandled Exception: Unable to load asset:
assets/json/campus_rules_pl.json E/flutter (18750): #0
PlatformAssetBundle.load
(package:flutter/src/services/asset_bundle.dart:227:7) E/flutter
(18750): E/flutter (18750): #1
AssetBundle.loadString
(package:flutter/src/services/asset_bundle.dart:68:27) E/flutter
(18750): E/flutter (18750): #2
_RulesCardState.loadFromJson (package:kampus_sggw/screens/map_screen/rules_card.dart:31:54)
E/flutter (18750): E/flutter (18750): #3
_RulesCardState.initState. (package:kampus_sggw/screens/map_screen/rules_card.dart:23:21)
E/flutter (18750): E/flutter (18750):
rules_card.dart where the Widget is defined:
class RulesCard extends StatefulWidget {
#override
_RulesCardState createState() => _RulesCardState();
}
class _RulesCardState extends State<RulesCard> {
CampusRules rulesListPL;
CampusRules rulesListEn;
#override
initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async
{
rulesListPL = await this.loadFromJson();
print(rulesListPL);
});
super.initState();
}
Future<CampusRules> loadFromJson() async {
Map<String, dynamic> campusRulesMap = jsonDecode(await CampusRules.getJsonSting());
final campusRules = CampusRules.fromJson(campusRulesMap);
return campusRules;
}
#override
Widget build(BuildContext context) {
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
Container(
height: 90.0,
child: DrawerHeader(
child: Text(
LocaleKeys.campus_rules.tr(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline3
),
decoration: BoxDecoration(
color: Theme.of(context).bannerTheme.backgroundColor
),
),
),
for (CampusRule campusRule in rulesListPL.campusRulesList)
SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: buildListTitle(context, campusRule),
),
],
),
);
}
Widget buildListTitle(BuildContext context, CampusRule rule) => ExpansionTile(
title: Text(
rule.rule,
style: Theme.of(context).textTheme.headline4,
),
children: [
for (CampusSubRule subRule in rule.subRulesList)
ListTile(
title:
Text(
subRule.subRule,
style: Theme.of(context).textTheme.headline4,
),
)
],
);
}
campus_rules.dart where is defined the model of CampusRules object:
import 'package:flutter/services.dart';
import 'package:json_annotation/json_annotation.dart';
part 'campus_rules.g.dart';
#JsonSerializable()
class CampusRules {
String name;
String lang;
List<CampusRule> campusRulesList;
CampusRules(
this.name,
this.lang,
this.campusRulesList,
);
factory CampusRules.fromJson(Map<String, dynamic> json) =>
_$CampusRulesFromJson(json);
static Future<String> getJsonSting() {
return rootBundle.loadString('assets/json/campus_rules_pl.json');
}
}
#JsonSerializable()
class CampusRule {
int ruleNumber;
String rule;
List<CampusSubRule> subRulesList;
CampusRule(
this.ruleNumber,
this.rule,
this.subRulesList,
);
factory CampusRule.fromJson(Map<String, dynamic> json) =>
_$CampusRuleFromJson(json);
}
#JsonSerializable()
class CampusSubRule {
int subRuleNumber;
String subRule;
CampusSubRule(
this.subRuleNumber,
this.subRule,
);
factory CampusSubRule.fromJson(Map<String, dynamic> json) =>
_$CampusSubRuleFromJson(json);
}
campus_rules.g.dart where is the auto generated code for Serialization
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'campus_rules.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
CampusRules _$CampusRulesFromJson(Map<String, dynamic> json) {
return CampusRules(
json['name'] as String,
json['lang'] as String,
(json['campusRulesList'] as List)
?.map((e) =>
e == null ? null : CampusRule.fromJson(e as Map<String, dynamic>))
?.toList(),
);
}
Map<String, dynamic> _$CampusRulesToJson(CampusRules instance) =>
<String, dynamic>{
'name': instance.name,
'lang': instance.lang,
'campusRulesList': instance.campusRulesList,
};
CampusRule _$CampusRuleFromJson(Map<String, dynamic> json) {
return CampusRule(
json['ruleNumber'] as int,
json['rule'] as String,
(json['subRulesList'] as List)
?.map((e) => e == null
? null
: CampusSubRule.fromJson(e as Map<String, dynamic>))
?.toList(),
);
}
Map<String, dynamic> _$CampusRuleToJson(CampusRule instance) =>
<String, dynamic>{
'ruleNumber': instance.ruleNumber,
'rule': instance.rule,
'subRulesList': instance.subRulesList,
};
CampusSubRule _$CampusSubRuleFromJson(Map<String, dynamic> json) {
return CampusSubRule(
json['subRuleNumber'] as int,
json['subRule'] as String,
);
}
Map<String, dynamic> _$CampusSubRuleToJson(CampusSubRule instance) =>
<String, dynamic>{
'subRuleNumber': instance.subRuleNumber,
'subRule': instance.subRule,
};
And the json file:
{
"name": "campus_rules",
"lang": "pl",
"campusRulesList": [
{
"ruleNumber": "1",
"rule": "I. Kampus Uczelni jest terenem ogólnodostępnym w godz. od 6:00 do 22:00. W pozostałym przedziale czasowym na terenie Kampusu mogą przebywać tylko osob do tego uprawnione:",
"subRulesList": [
{
"subRuleNumber": "1",
"subRule": "1) pracownicy Uczelni (a także osoby im towarzyszące) oraz osoby wykonujące prace zlecone na rzecz Uczelni posiadające indywidualne zezwolenia;"
},
{
"subRuleNumber": "2",
"subRule": "2) studenci i doktoranci SGGW oraz osoby im towarzyszące;"
},
{
"subRuleNumber": "3",
"subRule": "3) mieszkańcy domów studenckich. Domu Asystenckiego i Pokoi Gościnnych Ikar;"
},
{
"subRuleNumber": "3",
"subRule": "4) osoby korzystające z obiektów usługowych na terenie Kampusu do czasu ich zamknięcia."
}
]
},
{
"ruleNumber": "2",
"rule": "II. Każdy kto przebywa na terenie Kampusu SGGW zobowiązany jest do:",
"subRulesList": [
{
"subRuleNumber": "1",
"subRule": "1) przestrzegania ogólnie przyjętych norm postępowania w zakresie relacji międzyludzkich:"
},
{
"subRuleNumber": "2",
"subRule": "2) przestrzegania zasad poszanowania mienia wspólnego Uczelni, poszanowania zieleni, a zwłaszcza niezaśmiecania Kampusu;"
},
{
"subRuleNumber": "3",
"subRule": "3) właściwego korzystania z urządzeń, instalacji oraz wyposażenia budynków z uwzględnieniem ich przeznaczenia;"
},
{
"subRuleNumber": "4",
"subRule": "4) właściwego korzystania z dróg transportu samochodowego, parkingów dla samochodów oraz chodników dla pieszych;"
},
{
"subRuleNumber": "5",
"subRule": "5) zachowania zwykłych i nakazanych środków ostrożności przy trzymaniu psów oraz przy trzymaniu innych zwierząt."
}
]
},
{
"ruleNumber": "3",
"rule": "III. Na terenie Kampusu zabrania się:",
"subRulesList": [
{
"subRuleNumber": "1",
"subRule": "1) zakłócania porządku publicznego, agresywnego, napastliwego i nieobyczajnego zachowania oraz niszczenia mienia Uczelni;"
},
{
"subRuleNumber": "2",
"subRule": "2) spożywania alkoholu (nie dotyczy lokali konsumpcyjnych znajdujących się na terenie Kampusu SGGW oraz wydarzeń okazjonalnych lub cyklicznych organizowanychna terenie Kampusu SGGW, pod warunkiem wyrażenia przez Władze Uczelni zgody na spożywanie alkoholu podczas takiego wydarzenia), przebywania w stanie nietrzeźwym oraz pod wpływem innych środków odurzających;"
},
{
"subRuleNumber": "3",
"subRule": "3) wnoszenia i posiadania broni (z wyłączeniem osób pełniących służbę ochrony) i innych przedmiotów mogących stanowić zagrożenie bezpieczeństwa, w szczególności: materiałów wybuchowych, wyrobów pirotechnicznych, środków odurzających lub psychotropowych;"
},
{
"subRuleNumber": "4",
"subRule": "4) organizowania ognisk;"
},
{
"subRuleNumber": "5",
"subRule": "5) grillowania poza miejscami do tego wyznaczonymi;"
},
{
"subRuleNumber": "6",
"subRule": "6) wyprowadzania psów bez smyczy i kagańców oraz pozastawiania ich bez opieki;"
},
{
"subRuleNumber": "7",
"subRule": "7) parkowania pojazdów poza wyznaczonymi miejscami;"
},
{
"subRuleNumber": "8",
"subRule": "8) prowadzenia handlu obwoźnego i akwizycji bez zgody Władz Uczelni."
}
]
},
{
"ruleNumber": "4",
"rule": "VII. Osoby odpowiedzialne za sprawowanie nadzoru na terenie Kampusu SGGW. a szczególnie pracownicy Straży Akademickiej oraz monitoringu obiektów są uprawnione i zobowiązane do:",
"subRulesList": [
{
"subRuleNumber": "1",
"subRule": "1) ograniczania wstępu na teren Kampusu osobom nieupoważnionym, a w przypadku ujawnienia naruszeń postanowień Regulaminu żądania opuszczenia terenu Kampusu;"
},
{
"subRuleNumber": "2",
"subRule": "2) zwracania szczególnej uwagi na osoby, które swoim zachowaniem budzą uzasadnione podejrzenia zakłócenia porządku publicznego i reagowania w sytuacjach zagrożenia;"
},
{
"subRuleNumber": "3",
"subRule": "3) współdziałania, zgodnie z Prawem o Szkolnictwie Wyższym i Statutem Uczelni, w zakresie bezpieczeństwa z właściwymi terenowo jednostkami Policji. Straży Miejskiej, a w przypadku jakiegokolwiek zagrożenia wezwania grup interwencyjnych czy innych służb miejskich lub ratunkowych (Straż Pożarna. Pogotowie Ratunkowe);"
},
{
"subRuleNumber": "4",
"subRule": "4) kontrolowania uprawnień do przebywania na terenie Kampusu SGGW."
}
]
}
]
}

You're trying to access rulesListPL without waiting for loadFromJson() to complete and assign the result to it. So, you need a loading state:
#override
Widget build(BuildContext context) {
// If rulesListPL has not initialized yet
if (rulesListPL == null) {
// Display your loading screen instead
return Center(
child: CircularProgressIndicator(),
);
}
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
Container(
height: 90.0,
child: DrawerHeader(
child: Text(LocaleKeys.campus_rules.tr(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline3),
decoration: BoxDecoration(
color: Theme.of(context).bannerTheme.backgroundColor),
),
),
for (CampusRule campusRule in rulesListPL.campusRulesList)
SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: buildListTitle(context, campusRule),
),
],
),
);
}

Thanks to Stewie answer I added some code to handle refresh after it is loaded:
class _RulesCardState extends State<RulesCard> with TickerProviderStateMixin{
CampusRules rulesListPL;
CampusRules rulesListEn;
AnimationController controller;
#override
initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async
{
rulesListPL = await this.loadFromJson();
print(rulesListPL);
});
controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: true);
super.initState();
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
Future<CampusRules> loadFromJson() async {
Map<String, dynamic> campusRulesMap = jsonDecode(await CampusRules.getJsonSting());
final campusRules = CampusRules.fromJson(campusRulesMap);
return campusRules;
}
#override
Widget build(BuildContext context) {
// If rulesListPL has not initialized yet
if (rulesListPL == null) {
// Display your loading screen instead
return Center(
child: CircularProgressIndicator(
value: controller.value,
),
);
}
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
Container(
height: 90.0,
child: DrawerHeader(
child: Text(
LocaleKeys.campus_rules.tr(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline3
),
decoration: BoxDecoration(
color: Theme.of(context).bannerTheme.backgroundColor
),
),
),
for (CampusRule campusRule in rulesListPL.campusRulesList)
SingleChildScrollView(
physics: BouncingScrollPhysics(),
child: buildListTitle(context, campusRule),
),
],
),
);
}

Related

There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner'

My dropdown working as expected . but when I selected a item my app crashing with error
There should be exactly one item with [DropdownButton]'s value: Instance of 'Partner'.
Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
First I declare my variable in class
class _MultipleTestBookingState extends State<MultipleTestBooking> {
Partner? _selectedLab;
Datum? _selectedTest;
....................
declare with Partner?_selectedLab; because my dropdown menu takes in a list of Partners
Then using this variable to show the selected value in my dropdown
Container(
child: FutureBuilder<List<Partner>>(
future: AllPathLab(),
builder:
(BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState !=ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
return DropdownButton<Partner>(
value: _selectedLab,
hint: Text("Select Lab"),
items: snapshot.data.map((Partner data) =>
DropdownMenuItem<Partner>(
child: Text("${data.partnerName}"),
value: data,
)
).toList().cast<DropdownMenuItem<Partner>>(),
onChanged: (value){
setState(() {
_selectedLab=value;
encLabId = value!.encPartnerId;
GetTestByLab();
});
}
);
}
return Text("Waiting for Internet Connection");
},
),
),
Full code with my JSON response
So from the data that you provided i have created the code below:
import 'package:date_time_picker/date_time_picker.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/Patner.dart';
import 'package:flutter_app/dataModel.dart';
import 'package:http/http.dart' as http;
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
));
}
class MyApp extends StatefulWidget {
const MyApp({Key key}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Partner _selectedLab;
Datum _selectedTest;
Future getAllPathLabResults;
Future getTestByLabResult;
String encLabId = '';
void initState() {
super.initState();
getAllPathLabResults = allPathLab();
getTestByLabResult = getTestByLab();
}
String _selectedDate = DateTime.now().toString();
Future<List<Partner>> allPathLab() async {
String jsonData = jsonstring;
final model = modelFromJson(jsonData);
print("This is the list length : ${model.partner.length}");
List<Partner> arrData = model.partner;
// this Future is for sample as you will be fetching the api data remove this one
Future.delayed(Duration(seconds: 3));
return arrData;
}
Future<List<Datum>> getTestByLab() async {
print("This is the Id :$encLabId");
_selectedTest = null;
var response = await http.post(
Uri.parse("http://medbo.digitalicon.in/api/medboapi/GetTestByLab"),
body: ({"EncId": encLabId}));
if (response.statusCode == 200) {
final dataModel = dataModelFromJson(response.body);
print(dataModel.data.length);
for (final item in dataModel.data) {
print("This is hte test name :${item.testName}");
}
List<Datum> arrData = dataModel.data;
return arrData;
}
return [];
}
#override
Widget build(BuildContext context) {
var screenWidth = MediaQuery.of(context).size.width;
var screenHeight = MediaQuery.of(context).size.height;
var blockSizeHorizontal = (screenWidth / 100);
var blockSizeVertical = (screenHeight / 100);
return Scaffold(
body: SafeArea(
child: Container(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: ListTile(
title: Text("Booking Information",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 5,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
)),
subtitle: Text("Preferred Visit Date"),
),
),
Container(
margin: EdgeInsets.only(left: 20),
padding: EdgeInsets.only(left: 0, right: 150),
decoration: BoxDecoration(
color: Colors.lightBlue[50],
borderRadius: BorderRadius.all(Radius.circular(12)),
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: DateTimePicker(
initialValue: DateTime.now().toString(),
//initialValue:'', // initialValue or controller.text can be null, empty or a DateTime string otherwise it will throw an error.
type: DateTimePickerType.date,
dateLabelText: 'Select Date',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 3.5,
fontFamily: 'Poppins',
color: Colors.green,
letterSpacing: 2.0,
),
firstDate: DateTime.now(),
lastDate: DateTime.now().add(Duration(days: 30)),
// This will add one year from current date
validator: (value) {
return null;
},
onChanged: (value) {
if (value.isNotEmpty) {
setState(() {
_selectedDate = value;
});
}
},
onSaved: (value) {
if (value.isNotEmpty) {
_selectedDate = value;
}
},
),
),
),
ListTile(
title: Text(
"Select Pathological Lab",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 4.0,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
),
),
Container(
child: FutureBuilder<List<Partner>>(
future: getAllPathLabResults,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
List<Partner> data =
snapshot.hasData ? snapshot.data : [];
return DropdownButton<Partner>(
value: _selectedLab,
hint: Text("Select Lab"),
//underline: SizedBox(),
//isExpanded: true,
items: data
.map((Partner data) => DropdownMenuItem<Partner>(
child: Text("${data.partnerName}"),
value: data,
))
.toList()
.cast<DropdownMenuItem<Partner>>(),
onChanged: (value) {
setState(() {
_selectedLab = value;
encLabId = value.encPartnerId;
getTestByLabResult = getTestByLab();
});
//GetTestByLab(value!.encPartnerId); // passing encid to my next API function
// GetTestByLab();
},
);
}
return Text("Waiting for Internet Connection");
},
),
),
//=========================================================== Dependent drop down===================================
ListTile(
title: Text(
"Test Name",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal * 4.0,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
),
),
Container(
child: FutureBuilder<List<Datum>>(
future: getTestByLabResult,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return CircularProgressIndicator();
}
if (snapshot.hasError) {
return Text("Select a Lab for your Test");
}
if (snapshot.hasData) {
List<Datum> data = snapshot.hasData ? snapshot.data : [];
return DropdownButton<Datum>(
value: _selectedTest,
hint: Text(""),
//underline: SizedBox(),
//isExpanded: true,
items: data
.map((Datum data) => DropdownMenuItem<Datum>(
child: Text("${data.testName}"),
value: data,
))
.toList()
.cast<DropdownMenuItem<Datum>>(),
onChanged: (value) {
print("This is the value : ${value.testName}");
setState(() {
_selectedTest = value;
});
//GetTestByLab(value!.encPartnerId); // passing encid to my next API function
});
}
return Text("Waiting for Internet Connection");
},
),
),
],
),
),
),
);
}
}
// used this as a sample
String jsonstring = '''{
"Status": "1",
"Message": "",
"Partner": [
{
"EncPartnerId": "IujyQXg8KZg8asLvK/FS7g==",
"PartnerName": "dasfdsf"
},
{
"EncPartnerId": "pEl2B9kuumKRxIxLJO76eQ==",
"PartnerName": "partner172"
},
{
"EncPartnerId": "eYwtNBXR6P/JDtsIwr+Bvw==",
"PartnerName": "nnkb"
},
{
"EncPartnerId": "kFgorcFF0G6RQD4W+LwWnQ==",
"PartnerName": "nnkjj"
},
{
"EncPartnerId": "U4exk+vfMGrn7cjNUa/PBw==",
"PartnerName": "mahadev"
},
{
"EncPartnerId": "tqkaSjTFgDf0612mp9mbsQ==",
"PartnerName": null
},
{
"EncPartnerId": "0aruO0FbYOu5IerRBxdT8w==",
"PartnerName": "Suraksha Diagnostics"
},
{
"EncPartnerId": "65gtodyhbtdInTsJWr1ZkA==",
"PartnerName": "Rasomoy pvt. Hospital"
},
{
"EncPartnerId": "LEuT1eIlpLEMAAkZme3wpQ==",
"PartnerName": "Tangra medical House"
},
{
"EncPartnerId": "q8O8YMzYKXSB4RtkX4k7Lw==",
"PartnerName": "Partner new"
}
]
}''';
Models for the apis:
// To parse this JSON data, do
//
// final model = modelFromJson(jsonString);
import 'dart:convert';
Model modelFromJson(String str) => Model.fromJson(json.decode(str));
String modelToJson(Model data) => json.encode(data.toJson());
class Model {
Model({
this.status,
this.message,
this.partner,
});
String status;
String message;
List<Partner> partner;
factory Model.fromJson(Map<String, dynamic> json) => Model(
status: json["Status"],
message: json["Message"],
partner:
List<Partner>.from(json["Partner"].map((x) => Partner.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Partner": List<dynamic>.from(partner.map((x) => x.toJson())),
};
}
class Partner {
Partner({
this.encPartnerId,
this.partnerName,
});
String encPartnerId;
String partnerName;
factory Partner.fromJson(Map<String, dynamic> json) => Partner(
encPartnerId: json["EncPartnerId"],
partnerName: json["PartnerName"] == null ? null : json["PartnerName"],
);
Map<String, dynamic> toJson() => {
"EncPartnerId": encPartnerId,
"PartnerName": partnerName == null ? null : partnerName,
};
}
second api parsing model
// To parse this JSON data, do
//
// final dataModel = dataModelFromJson(jsonString);
import 'dart:convert';
DataModel dataModelFromJson(String str) => DataModel.fromJson(json.decode(str));
String dataModelToJson(DataModel data) => json.encode(data.toJson());
class DataModel {
DataModel({
this.status,
this.message,
this.data,
});
String status;
String message;
List<Datum> data;
factory DataModel.fromJson(Map<String, dynamic> json) => DataModel(
status: json["Status"],
message: json["Message"],
data: json["Data"] == null
? []
: List<Datum>.from(json["Data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Data":
data == null ? [] : List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.testId,
this.encTestId,
this.testName,
this.noOfPartner,
this.testFee,
this.discountedFee,
this.bookingFee,
this.reportTime,
this.note,
this.createBy,
this.createDate,
this.modBy,
this.modDate,
this.activeStatus,
this.permission,
});
String testId;
dynamic encTestId;
String testName;
dynamic noOfPartner;
dynamic testFee;
dynamic discountedFee;
dynamic bookingFee;
dynamic reportTime;
dynamic note;
dynamic createBy;
dynamic createDate;
dynamic modBy;
dynamic modDate;
dynamic activeStatus;
dynamic permission;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
testId: json["TestId"],
encTestId: json["EncTestId"],
testName: json["TestName"],
noOfPartner: json["NoOfPartner"],
testFee: json["TestFee"],
discountedFee: json["DiscountedFee"],
bookingFee: json["BookingFee"],
reportTime: json["ReportTime"],
note: json["Note"],
createBy: json["CreateBy"],
createDate: json["CreateDate"],
modBy: json["ModBy"],
modDate: json["ModDate"],
activeStatus: json["ActiveStatus"],
permission: json["Permission"],
);
Map<String, dynamic> toJson() => {
"TestId": testId,
"EncTestId": encTestId,
"TestName": testName,
"NoOfPartner": noOfPartner,
"TestFee": testFee,
"DiscountedFee": discountedFee,
"BookingFee": bookingFee,
"ReportTime": reportTime,
"Note": note,
"CreateBy": createBy,
"CreateDate": createDate,
"ModBy": modBy,
"ModDate": modDate,
"ActiveStatus": activeStatus,
"Permission": permission,
};
}
So when you initially fetch the data based on the id and select the second dropdown. now when you change the lab you have the make the selected text to null.
and you are are also using the futurebuilder method in wrong manner as there is setstate getting called it is creating multiple rebuids and giving error.
please run the code and check if its working.

How to display Nested JSON data?

I'm trying to display DietName from Data{} || PartnerName from PartnerData[] || DayName from DayList[]. As those data inside another ArrayList of data I'm facing problem with correct syntax to display those data.
{
"Status": "1",
"Message": "",
"Data": {
"EncDietId": "pEl2B9kuumKRxIxLJO76eQ==",
"DietName": "dietcian2",
"Email": null,
"Phone": null,
"AlternatePhone": null,
"Image": "http://mypain/Doctor/65AUEYyryTD2UKBRV.jpg",
"Description": null,
"Fee": null,
"DiscountedFee": null,
"BookingFee": null,
"VisitDay": null,
"TimeFrom": null,
"TimeTo": null
},
"PartnerData": [
{
"PartnerId": "13",
"EncPartnerId": "65gtodyhbtdInTsJWr1ZkA==",
"PartnerName": "Rasomoy pvt. Hospital",
"PartnerAddress": "Kol,Kol,Kol,Wb",
"Fee": "1200",
"DiscountedFee": "900",
"BookingFee": "500",
"DayList": [
{
"DayName": "Wednesday",
"TimeFrom": "10:00",
"TimeTo": "16:00"
},
{
"DayName": "Friday",
"TimeFrom": "10:00",
"TimeTo": "16:00"
},
{
"DayName": "Saturday",
"TimeFrom": "10:00",
"TimeTo": "16:00"
}
]
}
]
}
My API function .
Future<List<PartnerDatum>> dietcianDetailsApi() async {
var jsonResponse;
var response = await http.post(
Uri.parse("http://myapin/api/api/DietDetails"),
body: ({
'EncId ': pEl2tetIxLJO76eQ== //(encDietcianIdRef)
}));
if (response.statusCode == 200) {
print("Correct");
print(response.body);
jsonResponse = json.decode(response.body.toString());
print(jsonResponse);
DietDetailsModel dataModel = dietDetailsModelFromJson(response.body);
print(dataModel.partnerData.length);
for (final item in dataModel.partnerData)
print(item.partnerName);
List<PartnerDatum> arrData =dataModel.partnerData;
print(arrData[1].partnerName);
return arrData;
} else {
print("Wrong Url");
print(response.body);
throw Exception("Faild to fetch");
}
//return AllDietician();
}
Try to Print my JSON data in ListView builder .
Container(
height: blockSizeVertical*30,//38
//color: Colors.blueAccent,
child: FutureBuilder(
future: dietcianDetailsApi(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
// if (snapshot.connectionState !=ConnectionState.done) {
// return CircularProgressIndicator();
// }
if (snapshot.hasError) {
return Text("Somthing went wrong");
}
if (snapshot.hasData) {
return ListView.builder(
scrollDirection: Axis.horizontal,
physics: BouncingScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.length,
itemBuilder: (BuildContext context, int index) =>
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
width: blockSizeHorizontal*80,
margin: EdgeInsets.all(10),
child: Stack(children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(height: blockSizeVertical*0.5),
Text(
'${snapshot.data[index].partnerName}',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: blockSizeHorizontal*3.5,
fontFamily: 'Poppins',
color: Theme.of(context).primaryColor,
),
textAlign: TextAlign.center,
),
SizedBox(height: blockSizeVertical*0.8),
Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Center(
child: Text(
'PartnerAddress : ${snapshot.data[index].partnerAddress} Fee: ${snapshot.data[index].fee} || DiscountedFee: ${snapshot.data[index].discountedFee} ',//put email
style: TextStyle(
fontFamily: 'Poppins',
fontSize: blockSizeHorizontal*2.5,
color: Theme.of(context).primaryColor),
textAlign: TextAlign.center,
maxLines: 4,
),
),
),
]
),
Positioned(
bottom: 5,
left: 2,
child: Padding(
padding: const EdgeInsets.only(left:15.0, bottom: 5),
child: InkWell(
onTap: () {
},
child: Container(
alignment: Alignment.center,
height: blockSizeVertical*5,
width: blockSizeHorizontal*30,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(10),
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.topRight,
colors: [
Theme.of(context).primaryColor,
Theme.of(context).accentColor
],
),
),
child: Text(
'Show Details',
style: TextStyle(
color: Colors.white,
fontSize: blockSizeHorizontal*2.7,
fontWeight: FontWeight.bold,
fontFamily: 'Poppins',
),
),
),
),
),
),
]),
),
);
}
return Text("Error while calling");
},
),
),
My Model class
import 'package:meta/meta.dart';
import 'dart:convert';
DietDetailsModel dietDetailsModelFromJson(String str) => DietDetailsModel.fromJson(json.decode(str));
String dietDetailsModelToJson(DietDetailsModel data) => json.encode(data.toJson());
class DietDetailsModel {
DietDetailsModel({
required this.status,
required this.message,
required this.data,
required this.partnerData,
});
String status;
String message;
Data data;
List<PartnerDatum> partnerData;
factory DietDetailsModel.fromJson(Map<String, dynamic> json) => DietDetailsModel(
status: json["Status"],
message: json["Message"],
data: Data.fromJson(json["Data"]),
partnerData: List<PartnerDatum>.from(json["PartnerData"].map((x) => PartnerDatum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"Status": status,
"Message": message,
"Data": data.toJson(),
"PartnerData": List<dynamic>.from(partnerData.map((x) => x.toJson())),
};
}
class Data {
Data({
required this.encDietId,
required this.dietName,
required this.email,
required this.phone,
required this.alternatePhone,
required this.image,
required this.description,
required this.fee,
required this.discountedFee,
required this.bookingFee,
required this.visitDay,
required this.timeFrom,
required this.timeTo,
});
String encDietId;
String dietName;
dynamic email;
dynamic phone;
dynamic alternatePhone;
String image;
dynamic description;
dynamic fee;
dynamic discountedFee;
dynamic bookingFee;
dynamic visitDay;
dynamic timeFrom;
dynamic timeTo;
factory Data.fromJson(Map<String, dynamic> json) => Data(
encDietId: json["EncDietId"],
dietName: json["DietName"],
email: json["Email"],
phone: json["Phone"],
alternatePhone: json["AlternatePhone"],
image: json["Image"],
description: json["Description"],
fee: json["Fee"],
discountedFee: json["DiscountedFee"],
bookingFee: json["BookingFee"],
visitDay: json["VisitDay"],
timeFrom: json["TimeFrom"],
timeTo: json["TimeTo"],
);
Map<String, dynamic> toJson() => {
"EncDietId": encDietId,
"DietName": dietName,
"Email": email,
"Phone": phone,
"AlternatePhone": alternatePhone,
"Image": image,
"Description": description,
"Fee": fee,
"DiscountedFee": discountedFee,
"BookingFee": bookingFee,
"VisitDay": visitDay,
"TimeFrom": timeFrom,
"TimeTo": timeTo,
};
}
class PartnerDatum {
PartnerDatum({
required this.partnerId,
required this.encPartnerId,
required this.partnerName,
required this.partnerAddress,
required this.fee,
required this.discountedFee,
required this.bookingFee,
required this.dayList,
});
String partnerId;
String encPartnerId;
String partnerName;
String partnerAddress;
String fee;
String discountedFee;
String bookingFee;
List<DayList> dayList;
factory PartnerDatum.fromJson(Map<String, dynamic> json) => PartnerDatum(
partnerId: json["PartnerId"],
encPartnerId: json["EncPartnerId"],
partnerName: json["PartnerName"],
partnerAddress: json["PartnerAddress"],
fee: json["Fee"],
discountedFee: json["DiscountedFee"],
bookingFee: json["BookingFee"],
dayList: List<DayList>.from(json["DayList"].map((x) => DayList.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"PartnerId": partnerId,
"EncPartnerId": encPartnerId,
"PartnerName": partnerName,
"PartnerAddress": partnerAddress,
"Fee": fee,
"DiscountedFee": discountedFee,
"BookingFee": bookingFee,
"DayList": List<dynamic>.from(dayList.map((x) => x.toJson())),
};
}
class DayList {
DayList({
required this.dayName,
required this.timeFrom,
required this.timeTo,
});
String dayName;
String timeFrom;
String timeTo;
factory DayList.fromJson(Map<String, dynamic> json) => DayList(
dayName: json["DayName"],
timeFrom: json["TimeFrom"],
timeTo: json["TimeTo"],
);
Map<String, dynamic> toJson() => {
"DayName": dayName,
"TimeFrom": timeFrom,
"TimeTo": timeTo,
};
}
Since your deserialization seems to work, this is how you would access the first dayname in your list:
final firstPartnerDatum = myDietDetailsModel.partnerData[0];
final dayList = firstPartnerDatum.dayList[0];
final dayName = dayList.dayName;

Unhandled Exception: NoSuchMethodError: The method 'map' was called on null when try to retrieve data from the API

I'm trying to get JSON data from an API in my project. However, I came to an error and I'm completely stuck. I'm fairly new when it comes to deserializing JSON objects so appreciate your help on this.
This is my JSON file
{
"status": 200,
"data": [
{
"id": 1,
"title": "Down-sized 4thgeneration leverage",
"description": "Distinctio voluptas ea aliquid",
"address": "2755 Raul Estate\nWest Ervin, AZ 14265-2763",
"postcode": "42503-7193",
"phoneNumber": "387-842-0455x71431",
"latitude": "-60.964344",
"longitude": "-12.024244",
"image": {
"small": "http://lorempixel.com/200/200/cats/1/",
"medium": "http://lorempixel.com/400/400/cats/1/",
"large": "http://lorempixel.com/800/800/cats/1/"
}
},
{
"id": 2,
"title": "Optional intermediate orchestration",
"description": "Quia unde officiis ut eum",
"postcode": "06445-4404",
"phoneNumber": "103-350-9440x83127",
"latitude": "-84.165738",
"longitude": "62.221246",
"image": {
"small": "http://lorempixel.com/200/200/cats/2/",
"medium": "http://lorempixel.com/400/400/cats/2/",
"large": "http://lorempixel.com/800/800/cats/2/"
}
}
]
}
My part of my home file as follows:
body: Container(
child: Column(
children: [
///////// Future Builder checks the API service getusers() future method every refreshed time
Expanded(child: FutureBuilder(
future: apiService.getCars(),
builder: (context , snapshot){
if(snapshot.hasData)
{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index){
////// User List item button
return GestureDetector(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CarDetails(
car: snapshot.data[index].data[index].title,
)),
);
},
child:
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow( color: Colors.grey.withOpacity(0.3),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 5),
)
],
),
margin: EdgeInsets.symmetric(horizontal: 10 , vertical: 10),
padding: EdgeInsets.symmetric(horizontal: 10 , vertical: 10),
child: ListTile(
title: Text( snapshot.data[index].datalist[index].title , style: TextStyle(
fontSize: 18,color: Colors.black
),),
subtitle: Text( 'car Name', style: TextStyle(
fontSize: 18,color: Colors.black
),),
),
),
);
});
}else{
//////// Loading Circle from Spinkit Plugin
return Container(
child: Center(
child: SpinKitCircle(
color: Colors.orange,
),
),
);
}
},
))
],
) ,
),
This is my bean class(car.dart)
import 'dart:convert';
Car carFromJson(String str) => Car.fromJson(json.decode(str));
String carToJson(Car data) => json.encode(data.toJson());
class Car {
Car({
this.status,
this.data,
});
int status;
List<Datum> data;
factory Car.fromJson(Map<String, dynamic> json) => Car(
status: json["status"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
class Datum {
Datum({
this.id,
this.title,
this.description,
this.address,
this.postcode,
this.phoneNumber,
this.latitude,
this.longitude,
this.image,
});
int id;
String title;
String description;
String address;
String postcode;
String phoneNumber;
String latitude;
String longitude;
Image image;
factory Datum.fromJson(Map<String, dynamic> json) => Datum(
id: json["id"],
title: json["title"],
description: json["description"],
address: json["address"],
postcode: json["postcode"],
phoneNumber: json["phoneNumber"],
latitude: json["latitude"],
longitude: json["longitude"],
image: Image.fromJson(json["image"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"title": title,
"description": description,
"address": address,
"postcode": postcode,
"phoneNumber": phoneNumber,
"latitude": latitude,
"longitude": longitude,
"image": image.toJson(),
};
}
class Image {
Image({
this.small,
this.medium,
this.large,
});
String small;
String medium;
String large;
factory Image.fromJson(Map<String, dynamic> json) => Image(
small: json["small"],
medium: json["medium"],
large: json["large"],
);
Map<String, dynamic> toJson() => {
"small": small,
"medium": medium,
"large": large,
};
}
This is my get cars method and the JSON response body
Future<List<Car>> getCars() async {
final response = await http.get(Uri.parse(apiUrl));
///// checking the status code is successful
if (response.statusCode == 200) {
return getCarList(response.body);
} else {
throw Exception('Unable to fetch data from API');
}
}
List<Car> getCarList(String responseBody) {
final parsed = json.decode(responseBody);
final List<dynamic> cars= parsed["data"];
return (cars.map((json) => Car.fromJson(json)).toList());
}
I am getting this error: "Unhandled Exception: NoSuchMethodError: The method 'map' was called on null."
Here is what my Debug Console says:
E/flutter ( 6246): [ERROR:flutter/lib/ui/ui_dart_state.cc(213)] Unhandled Exception: NoSuchMethodError: The method 'map' was called on null.
E/flutter ( 6246): Receiver: null
E/flutter ( 6246): Tried calling: map(Closure: (dynamic) => Datum)
E/flutter ( 6246): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:63:5)
E/flutter ( 6246): #1 new Car.fromJson (package:flutter_car_booking/car.dart:61:41)
E/flutter ( 6246): #2 RestAPIService.getCarList.<anonymous closure> (package:flutter_car_booking/api_service.dart:54:39)
E/flutter ( 6246): #3 MappedListIterable.elementAt (dart:_internal/iterable.dart:413:31)
E/flutter ( 6246): #4 ListIterator.moveNext (dart:_internal/iterable.dart:342:26)
E/flutter ( 6246): #5 new _GrowableList._ofEfficientLengthIterable (dart:core-patch/growable_array.dart:188:27)
E/flutter ( 6246): #6 new _GrowableList.of (dart:core-patch/growable_array.dart:150:28)
E/flutter ( 6246): #7 new List.of (dart:core-patch/array_patch.dart:50:28)
E/flutter ( 6246): #8 ListIterable.toList (dart:_internal/iterable.dart:213:44)
E/flutter ( 6246): #9 RestAPIService.getCarList (package:flutter_car_booking/api_service.dart:54:55)
E/flutter ( 6246): #10 RestAPIService.getCars (package:flutter_car_booking/api_service.dart:23:10)
E/flutter ( 6246): <asynchronous suspension>
The problem is you are passing respons.body["data"]["data"] to your Datum.fromJson() constructor but there is no such key in the json. on the other hand you are passing response.body["data"] to Car.fromJson() constructor which is a list of data that does not have "status" key in it.
Try changing your code as follows.
Future<Car> getCars() async {
final response = await http.get(Uri.parse(apiUrl));
///// checking the status code is successful
if (response.statusCode == 200) {
return getCarList(response.body);
} else {
throw Exception('Unable to fetch data from API');
}
}
Car getCarList(String responseBody) {
final Map<String, dynamic> cars= json.decode(responseBody);
return (Car.fromJson(cars));
}
and you Car class as follows.
class Car {
Car({
this.status,
this.data,
});
int status;
List<Datum> data;
factory Car.fromJson(Map<String, dynamic> json) => Car(
status: json["status"],
data: List<Datum>.from(json["data"].map((x) => Datum.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"status": status,
"data": List<dynamic>.from(data.map((x) => x.toJson())),
};
}
Change your build method as follows. because now you do not have a list from snapshot it is a Car object and it has the data property which has the list of Datum objects
body: Container(
child: Column(
children: [
///////// Future Builder checks the API service getusers() future method every refreshed time
Expanded(child: FutureBuilder<Car>(
future: apiService.getCars(),
builder: (BuildContext context ,AsyncSnapshot<Car> snapshot){
if(snapshot.hasData)
{
return ListView.builder(
itemCount: snapshot.data.data.length,
itemBuilder: (context, index){
////// User List item button
return GestureDetector(
onTap: (){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CarDetails(
car: snapshot.data.data[index].title,
)),
);
},
child:
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow( color: Colors.grey.withOpacity(0.3),
spreadRadius: 5,
blurRadius: 7,
offset: Offset(0, 5),
)
],
),
margin: EdgeInsets.symmetric(horizontal: 10 , vertical: 10),
padding: EdgeInsets.symmetric(horizontal: 10 , vertical: 10),
child: ListTile(
title: Text( snapshot.data.data[index].title , style: TextStyle(
fontSize: 18,color: Colors.black
),),
subtitle: Text( 'car Name', style: TextStyle(
fontSize: 18,color: Colors.black
),),
),
),
);
});
}else{
//////// Loading Circle from Spinkit Plugin
return Container(
child: Center(
child: SpinKitCircle(
color: Colors.orange,
),
),
);
}
},
))
],
) ,
),

flutter - json - NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'map' with matching arguments

I am trying to fetch all data from the nutritionx API that matches a text field and display it as a list
The goal is to let the user search food names and have them on the list.
Here is the documentation for nutritionx-
https://docs.google.com/document/d/1_q-K-ObMTZvO0qUEAxROrN3bwMujwAN25sLHwJzliK0/edit#
Here is an example response-
{
"branded": [
{
"food_name": "Grilled Cheese",
"image": null,
"serving_unit": "serving",
"nix_brand_id": "513fbc1283aa2dc80c000358",
"brand_name_item_name": "Claim Jumper Grilled Cheese",
"serving_qty": 1,
"nf_calories": 560,
"brand_name": "Claim Jumper",
"brand_type": 1,
"nix_item_id": "529e800af9655f6d3500c710"
},
{
"food_name": "Grilled Cheesewich",
"image": null,
"serving_unit": "serving",
"nix_brand_id": "521b95434a56d006cae29678",
"brand_name_item_name": "Red Robin Grilled Cheesewich",
"serving_qty": 1,
"nf_calories": 550,
"brand_name": "Red Robin",
"brand_type": 1,
"nix_item_id": "52cdccf0051cb9eb320054c6"
},
{
"food_name": "Grilled Cheese Melts",
"image": "https://d1r9wva3zcpswd.cloudfront.net/54ca49ac6f1a024b0f919764.jpeg",
"serving_unit": "slice",
"nix_brand_id": "51db37b5176fe9790a8988dd",
"brand_name_item_name": "Borden Grilled Cheese Melts",
"serving_qty": 1,
"nf_calories": 50,
"brand_name": "Borden",
"brand_type": 2,
"nix_item_id": "54ca48fc064e3a791d6737b0"
},
{
"food_name": "Kid's Grilled Cheese",
"image": null,
"serving_unit": "serving",
"nix_brand_id": "521b95494a56d006cae2a612",
"brand_name_item_name": "Larkburger Kid's Grilled Cheese",
"serving_qty": 1,
"nf_calories": 500,
"brand_name": "Larkburger",
"brand_type": 1,
"nix_item_id": "529e80ceea63d4933500fc87"
}
],
"self": [
{
"food_name": "grilled cheese",
"serving_unit": "sandwich",
"nix_brand_id": null,
"serving_qty": 1,
"nf_calories": 348.4,
"brand_name": null,
"uuid": "7e79cdfa-bb3f-4f3b-a292-3357aa35d31f",
"nix_item_id": null
},
{
"food_name": "cheeseburgers",
"serving_unit": "item",
"nix_brand_id": null,
"serving_qty": 1.5,
"nf_calories": 802.97,
"brand_name": null,
"uuid": "5a63f2af-34b2-4137-bf14-5d95eabcf12d",
"nix_item_id": null
}
],
"common": [
{
"food_name": "grilled cheese",
"image": "https://d2xdmhkmkbyw75.cloudfront.net/1763_thumb.jpg",
"tag_id": "1763",
"tag_name": "grilled cheese"
},
{
"food_name": "grilled cheeses",
"image": "https://d2xdmhkmkbyw75.cloudfront.net/1763_thumb.jpg",
"tag_id": "1763",
"tag_name": "grilled cheese"
},
{
"food_name": "grilled cheese cheeseburger melt",
"image": null,
"tag_id": "5901",
"tag_name": "grilled cheese burger"
},
{
"food_name": "grilled cheese cheeseburger",
"image": null,
"tag_id": "5901",
"tag_name": "grilled cheese burger"
},
{
"food_name": "grilled cheese burger",
"image": null,
"tag_id": "5901",
"tag_name": "grilled cheese burger"
}
]
}
Here is my code-
import 'dart:async';
import 'dart:convert';
import 'foodModel.dart';
import 'package:fit_app/fitness_app_theme.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<List<Autogenerated>> fetchDishes(http.Client client, String query) async {
final response = await client.get(
'https://trackapi.nutritionix.com/v2/search/instant?query=$query',
headers: {
"x-app-id": "26706c4b",
"x-app-key": "496693e69b3996ce96fec5eeb79a3c26",
},
);
return compute(parseDishes, response.body);
}
List<Autogenerated> parseDishes(String responseBody) {
final parsed = jsonDecode(responseBody);
print(parsed);
if(parsed is List)
{
return parsed.map<Autogenerated>((json) => Autogenerated.fromJson(json)).toList();
}
else
{
return [parsed];
}
}
class FoodPage extends StatefulWidget {
FoodPage({Key key}) : super(key: key);
#override
_FoodPageState createState() => _FoodPageState();
}
class _FoodPageState extends State<FoodPage> {
TextEditingController editingController = TextEditingController();
List<Autogenerated> dishes;
List<Autogenerated> tempDishes = List<Autogenerated>();
List<Autogenerated> dummySearchList = List<Autogenerated>();
Widget _widget = Container();
var energy;
#override
void initState() {
super.initState();
}
Future<List<Autogenerated>> filterSearchResults (String query) async{
_widget = FutureBuilder<List<Autogenerated>>(
future: fetchDishes(http.Client(), editingController.text),
builder: (context, snapshot) {
if (snapshot.hasData) {
dishes = snapshot.data;
tempDishes.clear();
tempDishes.addAll(dishes);
return ListView.builder(
itemCount: tempDishes.length,
itemBuilder: (context, index) {
return Card(
child: ListTile(
title: Text(tempDishes[index].common[index].foodName, style: TextStyle(color: Colors.white),),
subtitle: Text('Energy - $energy', style: TextStyle(color: Colors.white))
),
color: FitnessAppTheme.nearlyDark,);
},
);
} else
{
return Center(child: CircularProgressIndicator());
}
}
);
}
#override
Widget build(BuildContext context) {
return new Scaffold(
backgroundColor: FitnessAppTheme.darkBackground,
body: SafeArea(
top: true,
child: Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
style: TextStyle(color: Colors.white),
onChanged: (value) async {
await filterSearchResults(value);
},
controller: editingController,
decoration: InputDecoration(
hintStyle: TextStyle(color: FitnessAppTheme.white),
labelStyle: TextStyle(color: FitnessAppTheme.white),
labelText: "Search",
hintText: "Search",
prefixIcon: Icon(Icons.search, color: Colors.white,),
enabledBorder: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(25.0)),
borderSide: const BorderSide(color: Colors.white, width: 1.0)
),
border: const OutlineInputBorder()
),
),
),
Expanded(
child: _widget,
),
],
),
),
),
);
}
}
Here are the models-
class Autogenerated {
List<Branded> branded;
List<Self> self;
List<Common> common;
Autogenerated({this.branded, this.self, this.common});
Autogenerated.fromJson(Map<String, dynamic> json) {
if (json['branded'] != null) {
branded = new List<Branded>();
json['branded'].forEach((v) {
branded.add(new Branded.fromJson(v));
});
}
if (json['self'] != null) {
self = new List<Self>();
json['self'].forEach((v) {
self.add(new Self.fromJson(v));
});
}
if (json['common'] != null) {
common = new List<Common>();
json['common'].forEach((v) {
common.add(new Common.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.branded != null) {
data['branded'] = this.branded.map((v) => v.toJson()).toList();
}
if (this.self != null) {
data['self'] = this.self.map((v) => v.toJson()).toList();
}
if (this.common != null) {
data['common'] = this.common.map((v) => v.toJson()).toList();
}
return data;
}
}
class Branded {
String foodName;
String image;
String servingUnit;
String nixBrandId;
String brandNameItemName;
int servingQty;
int nfCalories;
String brandName;
int brandType;
String nixItemId;
Branded(
{this.foodName,
this.image,
this.servingUnit,
this.nixBrandId,
this.brandNameItemName,
this.servingQty,
this.nfCalories,
this.brandName,
this.brandType,
this.nixItemId});
Branded.fromJson(Map<String, dynamic> json) {
foodName = json['food_name'];
image = json['image'];
servingUnit = json['serving_unit'];
nixBrandId = json['nix_brand_id'];
brandNameItemName = json['brand_name_item_name'];
servingQty = json['serving_qty'];
nfCalories = json['nf_calories'];
brandName = json['brand_name'];
brandType = json['brand_type'];
nixItemId = json['nix_item_id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['food_name'] = this.foodName;
data['image'] = this.image;
data['serving_unit'] = this.servingUnit;
data['nix_brand_id'] = this.nixBrandId;
data['brand_name_item_name'] = this.brandNameItemName;
data['serving_qty'] = this.servingQty;
data['nf_calories'] = this.nfCalories;
data['brand_name'] = this.brandName;
data['brand_type'] = this.brandType;
data['nix_item_id'] = this.nixItemId;
return data;
}
}
class Self {
String foodName;
String servingUnit;
Null nixBrandId;
double servingQty;
double nfCalories;
Null brandName;
String uuid;
Null nixItemId;
Self(
{this.foodName,
this.servingUnit,
this.nixBrandId,
this.servingQty,
this.nfCalories,
this.brandName,
this.uuid,
this.nixItemId});
Self.fromJson(Map<String, dynamic> json) {
foodName = json['food_name'];
servingUnit = json['serving_unit'];
nixBrandId = json['nix_brand_id'];
servingQty = json['serving_qty'];
nfCalories = json['nf_calories'];
brandName = json['brand_name'];
uuid = json['uuid'];
nixItemId = json['nix_item_id'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['food_name'] = this.foodName;
data['serving_unit'] = this.servingUnit;
data['nix_brand_id'] = this.nixBrandId;
data['serving_qty'] = this.servingQty;
data['nf_calories'] = this.nfCalories;
data['brand_name'] = this.brandName;
data['uuid'] = this.uuid;
data['nix_item_id'] = this.nixItemId;
return data;
}
}
class Common {
String foodName;
String image;
String tagId;
String tagName;
Common({this.foodName, this.image, this.tagId, this.tagName});
Common.fromJson(Map<String, dynamic> json) {
foodName = json['food_name'];
image = json['image'];
tagId = json['tag_id'];
tagName = json['tag_name'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['food_name'] = this.foodName;
data['image'] = this.image;
data['tag_id'] = this.tagId;
data['tag_name'] = this.tagName;
return data;
}
}
Error-
Unhandled Exception: Exception: NoSuchMethodError: Class '_InternalLinkedHashMap<String, dynamic>' has no instance method 'map' with matching arguments.
E/flutter ( 8271): Receiver: _LinkedHashMap len:2
E/flutter ( 8271): Tried calling: map<Autogenerated>(Closure: (dynamic) => Autogenerated)
E/flutter ( 8271): Found: map<K2, V2>((K, V) => MapEntry<K2, V2>) => Map<K2, V2>
E/flutter ( 8271): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:54:5)
E/flutter ( 8271): #1 parseDishes (package:fit_app/ui_view/add_food.dart:21:17)
E/flutter ( 8271): #2 _IsolateConfiguration.apply (package:flutter/src/foundation/_isolates_io.dart:81:34)
E/flutter ( 8271): #3 _spawn.<anonymous closure> (package:flutter/src/foundation/_isolates_io.dart:88:65)
E/flutter ( 8271): #4 _spawn.<anonymous closure> (package:flutter/src/foundation/_isolates_io.dart:87:5)
E/flutter ( 8271): #5 Timeline.timeSync (dart:developer/timeline.dart:163:22)
E/flutter ( 8271): #6 _spawn (package:flutter/src/foundation/_isolates_io.dart:85:35)
E/flutter ( 8271): #7 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:286:17)
E/flutter ( 8271): #8 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
E/flutter ( 8271):
What am I doing wrong?
EDIT-
THE ERROR-
Unhandled Exception: Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Autogenerated'
E/flutter ( 8671): #0 parseDishes (package:fit_app/ui_view/add_food.dart:30:13)
E/flutter ( 8671): #1 _IsolateConfiguration.apply (package:flutter/src/foundation/_isolates_io.dart:81:34)
E/flutter ( 8671): #2 _spawn.<anonymous closure> (package:flutter/src/foundation/_isolates_io.dart:88:65)
E/flutter ( 8671): #3 _spawn.<anonymous closure> (package:flutter/src/foundation/_isolates_io.dart:87:5)
E/flutter ( 8671): #4 Timeline.timeSync (dart:developer/timeline.dart:163:22)
E/flutter ( 8671): #5 _spawn (package:flutter/src/foundation/_isolates_io.dart:85:35)
E/flutter ( 8671): #6 _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:286:17)
E/flutter ( 8671): #7 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)
E/flutter ( 8671):
EDIT-
i am setting a widget each time and using it in build-
_widget = FutureBuilder<List<Autogenerated>>(
future: fetchDishes(http.Client(), editingController.text),
builder: (context, snapshot) {
if (snapshot.hasData) {
dishes = snapshot.data;
tempDishes.clear();
tempDishes.addAll(dishes);
return ListView.builder(
itemCount: tempDishes[0].common.length,
itemBuilder: (context, index) {
print(tempDishes[0].common.length);
return Card(
child: ListTile(
title: Text(tempDishes[0].common[index].foodName),
subtitle: Text('Energy - $energy', style: TextStyle(color: Colors.white))
),
color: FitnessAppTheme.nearlyDark,);
},
);
} else
{
return Center(child: CircularProgressIndicator());
}
}
);

Can't decode/Parse Json type list<String> with this list<String> type Model in Dart

I wanted to create a drop down from json list. I am using app.quicktype.io to covert json to PODO (Plain Old dart Object)
Here is the My JSON data:
[
{
"country_name": "Andorra",
"alpha2_code": "AD",
"country_code": "376",
"states": [
{ "state_name": "Andorra la Vella" },
{ "state_name": "Canillo" }
]
},
]
And here is the PODO (Plain Old Dart Object) I created with app.quicktype.io:
class CountryDetailsModel {
CountryDetailsModel({
this.countryName,
this.alpha2Code,
this.countryCode,
this.states,
});
String countryName;
String alpha2Code;
String countryCode;
List<StateNames> states;
factory CountryDetailsModel.fromJson(Map<String, dynamic> json) =>
CountryDetailsModel(
countryName: json["country_name"],
alpha2Code: json["alpha2_code"],
countryCode: json["country_code"],
states: List<StateNames>.from(
json["states"].map((x) => StateNames.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"country_name": countryName,
"alpha2_code": alpha2Code,
"country_code": countryCode,
"states": List<dynamic>.from(states.map((x) => x.toJson())),
};
}
class StateNames {
StateNames({
this.stateName,
});
String stateName;
factory StateNames.fromJson(Map<String, dynamic> json) => StateNames(
stateName: json["state_name"],
);
Map<String, dynamic> toJson() => {
"state_name": stateName,
};
}
You can copy paste run full code below
In working demo, simulate network delay with 3 seconds
You can use FutureBuilder and use return countryDetailsModelFromJson(jsonString);
code snippet
Future<List<CountryDetailsModel>> getHttp() async {
String jsonString = ...
return countryDetailsModelFromJson(jsonString);
}
...
FutureBuilder(
future: _future,
builder:
(context, AsyncSnapshot<List<CountryDetailsModel>> snapshot) {
...
return DropdownButton<CountryDetailsModel>(
//isDense: true,
hint: Text('Choose'),
value: _selectedValue,
icon: Icon(Icons.check_circle_outline),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.blue[300],
),
onChanged: (CountryDetailsModel newValue) {
setState(() {
_selectedValue = newValue;
});
},
items: snapshot.data
.map<DropdownMenuItem<CountryDetailsModel>>(
(CountryDetailsModel value) {
return DropdownMenuItem<CountryDetailsModel>(
value: value,
child: Text(value.countryName),
);
}).toList(),
);
}
}
})
working demo
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
List<CountryDetailsModel> countryDetailsModelFromJson(String str) =>
List<CountryDetailsModel>.from(
json.decode(str).map((x) => CountryDetailsModel.fromJson(x)));
String countryDetailsModelToJson(List<CountryDetailsModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class CountryDetailsModel {
CountryDetailsModel({
this.countryName,
this.alpha2Code,
this.countryCode,
this.states,
});
String countryName;
String alpha2Code;
String countryCode;
List<StateNames> states;
factory CountryDetailsModel.fromJson(Map<String, dynamic> json) =>
CountryDetailsModel(
countryName: json["country_name"],
alpha2Code: json["alpha2_code"],
countryCode: json["country_code"],
states: List<StateNames>.from(
json["states"].map((x) => StateNames.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"country_name": countryName,
"alpha2_code": alpha2Code,
"country_code": countryCode,
"states": List<dynamic>.from(states.map((x) => x.toJson())),
};
}
class StateNames {
StateNames({
this.stateName,
});
String stateName;
factory StateNames.fromJson(Map<String, dynamic> json) => StateNames(
stateName: json["state_name"],
);
Map<String, dynamic> toJson() => {
"state_name": stateName,
};
}
void main() => runApp(MyApp());
/// This Widget is the main application widget.
class MyApp extends StatelessWidget {
static const String _title = 'Flutter Code Sample';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: _title,
home: Scaffold(
appBar: AppBar(title: const Text(_title)),
body: MyStatefulWidget(),
),
);
}
}
class MyStatefulWidget extends StatefulWidget {
MyStatefulWidget({Key key}) : super(key: key);
#override
_MyStatefulWidgetState createState() => _MyStatefulWidgetState();
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
CountryDetailsModel _selectedValue;
Future<List<CountryDetailsModel>> _future;
Future<List<CountryDetailsModel>> getHttp() async {
String jsonString = '''
[
{
"country_name": "Andorra",
"alpha2_code": "AD",
"country_code": "376",
"states": [
{ "state_name": "Andorra la Vella" },
{ "state_name": "Canillo" },
{ "state_name": "Encamp" },
{ "state_name": "La Massana" },
{ "state_name": "Les Escaldes" },
{ "state_name": "Ordino" },
{ "state_name": "Sant Julia de Loria" }
]
},
{
"country_name": "Azerbaijan",
"alpha2_code": "AZ",
"country_code": "994",
"states": [
{ "state_name": "Abseron" },
{ "state_name": "Baki Sahari" },
{ "state_name": "Ganca" },
{ "state_name": "Ganja" },
{ "state_name": "Kalbacar" },
{ "state_name": "Lankaran" },
{ "state_name": "Mil-Qarabax" },
{ "state_name": "Mugan-Salyan" },
{ "state_name": "Nagorni-Qarabax" },
{ "state_name": "Naxcivan" },
{ "state_name": "Priaraks" },
{ "state_name": "Qazax" },
{ "state_name": "Saki" },
{ "state_name": "Sirvan" },
{ "state_name": "Xacmaz" }
]
}]
''';
return countryDetailsModelFromJson(jsonString);
}
#override
void initState() {
_future = getHttp();
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: _future,
builder:
(context, AsyncSnapshot<List<CountryDetailsModel>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return DropdownButton<CountryDetailsModel>(
//isDense: true,
hint: Text('Choose'),
value: _selectedValue,
icon: Icon(Icons.check_circle_outline),
iconSize: 24,
elevation: 16,
style: TextStyle(color: Colors.deepPurple),
underline: Container(
height: 2,
color: Colors.blue[300],
),
onChanged: (CountryDetailsModel newValue) {
setState(() {
_selectedValue = newValue;
});
},
items: snapshot.data
.map<DropdownMenuItem<CountryDetailsModel>>(
(CountryDetailsModel value) {
return DropdownMenuItem<CountryDetailsModel>(
value: value,
child: Text(value.countryName),
);
}).toList(),
);
}
}
}));
}
}
Finally I found a solution.
Here is the Process:
List<CountryDetailsModel> countryDetails() {
List<Map> map = CountryData.countryData;
List<CountryDetailsModel> list =
map.map((json) => CountryDetailsModel.fromJson(json)).toList();
return list;
}
And for printing all countries:
countryDetails().
forEach((element) {
print(element.countryName);
});