Parsing json to model fails in flutter - flutter

I am trying to show data to listview but it doesn't show anything.there is json below ,am i doing something wrong,i tired to print the data in api call but i can print the data but not in the listview,
i having hardtime to understand what i doing wrong or correct.please help me on this
if (response.statusCode == 200) {
try {
if (status == true) {
var company_list = value['doc'];
for (int i = 0; i < company_list.length; i++) {
print(company_list);
var mobile_list = company_list["mobile"];
var email_list = company_list["email"];
company_model.add(CompanyModel.fromJson(company_list,mobile_list,email_list));
}
setState(() {
print("UI Updated");
});
} else {
final snackBar = SnackBar(content: Text(message));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
} catch (e) {
e.toString();
}
} else {
final snackBar = SnackBar(content: Text(message));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
Json
{
"status":true,
"doc":{
"mobile":[
"9961256754",
"8974525672"
],
"email":[
],
"_id":"5f3a0dfe88b9d50453e92133",
"name":"MRC Labour",
"terms":{
"english":"We Shall not be liable for any disputes arising between the users and the
labourers",
"malayalam":"We Shall not be liable for any disputes arising between the users and the
labourers"
}
}
}
Model
class CompanyModel {
String id = "";
String mobile = "";
String email = "";
String name = "";
String english = "";
String malayalam = "";
CompanyModel({this.id, this.mobile, this.email, this.name, this.english,this.malayalam});
CompanyModel.fromJson(json,mobile_list,email_list)
: id = json['_id'].toString(),
mobile = mobile_list,
email = email_list,
name = json['name'].toString(),
english = json['terms']['english'].toString(),
malayalam = json['terms']['malayalam'].toString();
}
When the debugger hit at this line it breaks without any errors company_model.add(CompanyModel.fromJson(data,mobile_list,email_list));
This is listview code
Container(
height: 80,
width: 100,
color: Colors.blueGrey[100],
padding: EdgeInsets.all(10),
child: ListView.separated(
separatorBuilder: (BuildContext context, int index) =>
const Divider(),
itemCount: company_model.length,
itemBuilder: (BuildContext context, int index) {
CompanyModel data = company_model[index];
print(data);
return Container(
height: 10,
color: Colors.green,
child: Text(data.name.toString(),style: TextStyle(color: Colors.black),),
);
},
),
),

First of all, your model is wrong, you're parsing a List (mobile and email) as a String in your model, also, you don't really need to pass 2 additional parameters to the function.
class CompanyModel {
List<String> mobile;
List<String> email;
String sId;
String name;
Terms terms;
CompanyModel({this.mobile, this.email, this.sId, this.name, this.terms});
CompanyModel.fromJson(Map<String, dynamic> json) {
mobile = json['mobile'].cast<String>();
email = json['email'].cast<String>();
sId = json['_id'];
name = json['name'];
terms = json['terms'] != null ? new Terms.fromJson(json['terms']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['mobile'] = this.mobile;
data['email'] = this.email;
data['_id'] = this.sId;
data['name'] = this.name;
if (this.terms != null) {
data['terms'] = this.terms.toJson();
}
return data;
}
}
class Terms {
String english;
String malayalam;
Terms({this.english, this.malayalam});
Terms.fromJson(Map<String, dynamic> json) {
english = json['english'];
malayalam = json['malayalam'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['english'] = this.english;
data['malayalam'] = this.malayalam;
return data;
}
}
Also, double check that you're initializing the company_model as something like: List company_model = [] otherwise it initialize as null and won't work the rest of your code.
if (response.statusCode == 200) {
try {
if (status == true) {
var company_json = value['doc'];
company_model.add(CompanyModel.fromJson(company_json));
setState(() {
print("UI Updated");
});
} else {
final snackBar = SnackBar(content: Text(message));
_scaffoldKey.currentState.showSnackBar(snackBar);
}
} catch (e) {
e.toString();
}
} else {
final snackBar = SnackBar(content: Text(message));
_scaffoldKey.currentState.showSnackBar(snackBar);
}

The best way to create model is in the link below
https://app.quicktype.io/
just put your json on as input on left side and select dart as language from left, you are good to go.

Related

how to solve null check operator in flutter

I have a problem here, I'm trying to call the API and the response in the console shows the json response, but the screen shows an error like below,
Previously I managed to do it but when I tried to call it with a different API the result was not what I wanted.
Is there anyone here who can help me solve this problem.
Here I attach the code
the models I have
class KurikulumModel {
String? status;
String? code;
List<Data>? data;
KurikulumModel({status, code, data});
KurikulumModel.fromJson(Map<String, dynamic> json) {
status = json['status'];
code = json['code'];
if (json['data'] != null) {
data = <Data>[];
json['data'].forEach((v) {
data!.add(Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['status'] = status;
data['code'] = code;
if (data != null) {
data['data'] = this.data!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Data {
String? id;
String? name;
String? idSemester;
String? smt;
String? idProdi;
String? prodi;
String? createdAt;
String? updatedAt;
String? createdBy;
String? updatedBy;
int? jumlahSksWajib;
int? jumlahSksPilihan;
int? jumlahSksSertifikat;
int? status;
int? stsHapus;
Data(
{id,
name,
idSemester,
smt,
idProdi,
prodi,
createdAt,
updatedAt,
createdBy,
updatedBy,
jumlahSksWajib,
jumlahSksPilihan,
jumlahSksSertifikat,
status,
stsHapus});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
idSemester = json['id_semester'];
smt = json['smt'];
idProdi = json['id_prodi'];
prodi = json['prodi'];
createdAt = json['created_at'];
updatedAt = json['updated_at'];
createdBy = json['created_by'];
updatedBy = json['updated_by'];
jumlahSksWajib = json['jumlah_sks_wajib'];
jumlahSksPilihan = json['jumlah_sks_pilihan'];
jumlahSksSertifikat = json['jumlah_sks_sertifikat'];
status = json['status'];
stsHapus = json['sts_hapus'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['id_semester'] = idSemester;
data['smt'] = smt;
data['id_prodi'] = idProdi;
data['prodi'] = prodi;
data['created_at'] = createdAt;
data['updated_at'] = updatedAt;
data['created_by'] = createdBy;
data['updated_by'] = updatedBy;
data['jumlah_sks_wajib'] = jumlahSksWajib;
data['jumlah_sks_pilihan'] = jumlahSksPilihan;
data['jumlah_sks_sertifikat'] = jumlahSksSertifikat;
data['status'] = status;
data['sts_hapus'] = stsHapus;
return data;
}
}
then i call
class KurikulumProvider extends ChangeNotifier {
Future<Data> getKurikulum() async {
String url = Constant.baseURL;
String token = await UtilSharedPreferences.getToken();
final response = await http.get(
Uri.parse(
'$url/auth/mhs_siakad/kurikulum',
),
headers: {
'Authorization': 'Bearer $token',
},
);
print(response.statusCode);
print(response.body);
if (response.statusCode == 200) {
return Data.fromJson(jsonDecode(response.body));
} else {
throw Exception('Token Expired!');
}
}
}
and this is when i want to call it in API
...
FutureBuilder<Data>(
future: kurikulumProvider.getKurikulum(),
builder: (context, snapshot) {
return Table(
border: TableBorder.all(color: Colors.grey),
children: [
TableRow(children: [
Column(children: [
Text('Nama Kurikulum', style: bold6)
]),
Column(children: [
Text('Program Studi', style: bold6)
]),
Column(children: [
Text('Masa Berlaku', style: bold6)
]),
]),
TableRow(
children: [
Column(children: [
Text(snapshot.data!.name.toString(),
style: regular6,
textAlign: TextAlign.center)
]), ...
the future is not completed yet but u already return the table modle.
you can listen to the snapshot is it already has data or not yet.
try changes your code like this
FutureBuilder<T>(
future: future,
builder: (
BuildContext context,
AsyncSnapshot<String> snapshot,
) {
if (snapshot.connectionState == ConnectionState.waiting) {
//return something
} else if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
//return error
} else if (snapshot.hasData) {
//return your table
} else {
//return empty data
}
} else {
//connection error return
}
},
),
i suggest to use any state management to handle this. provider/bloc to handle of the data.

Pagination new data Isn't added to the ListView.builder at the end instead refreshed replacing previous data

I have an API from where I am get 10 data entries on each hit. What I want to do is to add these entries at the end of the ListView.builder List. At the moment it refreshes the ListView.builder instead of populating more entries.
Code for the whole screen is quite longer so I trimmed down only for one type of entry.
class PaginatedScreen extends StatefulWidget {
const PaginatedScreen({Key? key}) : super(key: key);
#override
State<PaginatedScreen> createState() => _PaginatedScreenState();
}
class _PaginatedScreenState extends State<PaginatedScreen> {
final scrollController = ScrollController();
int offSetCurrent = 0;
bool hasMore = true;
bool isLoading = false;
#override
void initState(){
super.initState();
scrollController.addListener(() {
if (scrollController.position.maxScrollExtent == scrollController.offset) {
setState(() {
getDiscussion(offSetCurrent);
print('initial offSet: $offSetCurrent');
offSetCurrent = offSetCurrent + 10;
print('new offset $offSetCurrent');
});
}
});
}
#override
void dispose(){
scrollController.dispose();
super.dispose();
}
Future<PaginatedModel> getDiscussion(offSetCurrent) async {
// if (isLoading) return;
// isLoading = true;
SharedPreferences sp = await SharedPreferences.getInstance();
var parameters = {
'RangeFrom':offSetCurrent.toString(),
'AccessToken':sp.getString('AccessToken'),
'DiscussionID':'22848',
};
var urlfetch = Uri(
scheme: "https",
host: baseUrl,
path: discussionAPIPath,
queryParameters: parameters,
);
try {
http.Response response = await http.get(Uri.parse(urlfetch.toString()));
var data = jsonDecode(response.body.toString());
var snapshot = PaginatedModel.fromJson(data);
var itemsTotal = snapshot.courseLessonDetailsData!.first.discussionDetails!.first.discussionsMessages!.length;
if (itemsTotal < 10){
setState((){
hasMore = false;
});
}
print(data);
print('Discussion API HIT with offset $offSetCurrent');
// isLoading = false;
if (response.statusCode == 200) {
return PaginatedModel.fromJson(data);
}
else {
print(response.statusCode);
return PaginatedModel.fromJson(data);
}
}
catch (e) {
print(e.toString());
rethrow;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder(
future: getDiscussion(offSetCurrent),
builder: (dCtx, dSnapshot){
if (dSnapshot.hasData){
var itemCount = dSnapshot.data!.courseLessonDetailsData!.first.discussionDetails!.first.discussionsMessages!.length;
return ListView.builder(
controller: scrollController,
shrinkWrap: true,
itemCount: itemCount + 1,
itemBuilder: (context, idx){
if (idx < itemCount){
return Column(
children: List<Widget>.generate(dSnapshot.data!.courseLessonDetailsData!.first.discussionDetails!.length, (i) => Container(
margin: const EdgeInsets.all(10),
child: Column(
children: [
Html(data: dSnapshot.data!.courseLessonDetailsData!.first.discussionDetails!.first.discussionsMessages![idx].message.toString()),
],
),
))
);
}
else {
return Padding(
padding: EdgeInsets.symmetric(vertical: 32),
child: Center(
child: hasMore? CircularProgressIndicator() : Text('No More Data'),
),
);
}
}
);
}
else {
return const Center(
child: CircularProgressIndicator(),
);
}
}
),
);
}
}
Here is my Model:
class PaginatedModel {
PaginatedModel({
List<CourseLessonDetailsData>? courseLessonDetailsData,}){
_courseLessonDetailsData = courseLessonDetailsData;
}
PaginatedModel.fromJson(dynamic json) {
if (json['CourseLessonDetailsData'] != null) {
_courseLessonDetailsData = [];
json['CourseLessonDetailsData'].forEach((v) {
_courseLessonDetailsData?.add(CourseLessonDetailsData.fromJson(v));
});
}
}
List<CourseLessonDetailsData>? _courseLessonDetailsData;
PaginatedModel copyWith({ List<CourseLessonDetailsData>? courseLessonDetailsData,
}) => PaginatedModel( courseLessonDetailsData: courseLessonDetailsData ?? _courseLessonDetailsData,
);
List<CourseLessonDetailsData>? get courseLessonDetailsData => _courseLessonDetailsData;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
if (_courseLessonDetailsData != null) {
map['CourseLessonDetailsData'] = _courseLessonDetailsData?.map((v) => v.toJson()).toList();
}
return map;
}
}
class CourseLessonDetailsData {
CourseLessonDetailsData({
String? requestStatus,
List<DiscussionDetails>? discussionDetails,}){
_requestStatus = requestStatus;
_discussionDetails = discussionDetails;
}
CourseLessonDetailsData.fromJson(dynamic json) {
_requestStatus = json['request_status'];
if (json['DiscussionDetails'] != null) {
_discussionDetails = [];
json['DiscussionDetails'].forEach((v) {
_discussionDetails?.add(DiscussionDetails.fromJson(v));
});
}
}
String? _requestStatus;
List<DiscussionDetails>? _discussionDetails;
CourseLessonDetailsData copyWith({ String? requestStatus,
List<DiscussionDetails>? discussionDetails,
}) => CourseLessonDetailsData( requestStatus: requestStatus ?? _requestStatus,
discussionDetails: discussionDetails ?? _discussionDetails,
);
String? get requestStatus => _requestStatus;
List<DiscussionDetails>? get discussionDetails => _discussionDetails;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['request_status'] = _requestStatus;
if (_discussionDetails != null) {
map['DiscussionDetails'] = _discussionDetails?.map((v) => v.toJson()).toList();
}
return map;
}
}
class DiscussionDetails {
DiscussionDetails({
List<DiscussionsMessages>? discussionsMessages,}){
_discussionsMessages = discussionsMessages;
}
DiscussionDetails.fromJson(dynamic json) {
if (json['DiscussionsMessages'] != null) {
_discussionsMessages = [];
json['DiscussionsMessages'].forEach((v) {
_discussionsMessages?.add(DiscussionsMessages.fromJson(v));
});
}
}
List<DiscussionsMessages>? _discussionsMessages;
DiscussionDetails copyWith({ List<DiscussionsMessages>? discussionsMessages,
}) => DiscussionDetails( discussionsMessages: discussionsMessages ?? _discussionsMessages,
);
List<DiscussionsMessages>? get discussionsMessages => _discussionsMessages;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
if (_discussionsMessages != null) {
map['DiscussionsMessages'] = _discussionsMessages?.map((v) => v.toJson()).toList();
}
return map;
}
}
class DiscussionsMessages {
DiscussionsMessages({
String? messageID,
String? id,
String? studentName,
String? message,
String? replyMessage,
List<OtherStudentMessages>? otherStudentMessages,}){
_messageID = messageID;
_id = id;
_studentName = studentName;
_message = message;
_replyMessage = replyMessage;
_otherStudentMessages = otherStudentMessages;
}
DiscussionsMessages.fromJson(dynamic json) {
_messageID = json['MessageID'];
_id = json['ID'];
_studentName = json['StudentName'];
_message = json['Message'];
_replyMessage = json['ReplyMessage'];
if (json['OtherStudentMessages'] != null) {
_otherStudentMessages = [];
json['OtherStudentMessages'].forEach((v) {
_otherStudentMessages?.add(OtherStudentMessages.fromJson(v));
});
}
}
String? _messageID;
String? _id;
String? _studentName;
String? _message;
String? _replyMessage;
List<OtherStudentMessages>? _otherStudentMessages;
DiscussionsMessages copyWith({ String? messageID,
String? id,
String? studentName,
String? message,
String? replyMessage,
List<OtherStudentMessages>? otherStudentMessages,
}) => DiscussionsMessages( messageID: messageID ?? _messageID,
id: id ?? _id,
studentName: studentName ?? _studentName,
message: message ?? _message,
replyMessage: replyMessage ?? _replyMessage,
otherStudentMessages: otherStudentMessages ?? _otherStudentMessages,
);
String? get messageID => _messageID;
String? get id => _id;
String? get studentName => _studentName;
String? get message => _message;
String? get replyMessage => _replyMessage;
List<OtherStudentMessages>? get otherStudentMessages => _otherStudentMessages;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['MessageID'] = _messageID;
map['ID'] = _id;
map['StudentName'] = _studentName;
map['Message'] = _message;
map['ReplyMessage'] = _replyMessage;
if (_otherStudentMessages != null) {
map['OtherStudentMessages'] = _otherStudentMessages?.map((v) => v.toJson()).toList();
}
return map;
}
}
class OtherStudentMessages {
OtherStudentMessages({
String? replyID,
String? repliedBy,
String? replyMessage,}){
_replyID = replyID;
_repliedBy = repliedBy;
_replyMessage = replyMessage;
}
OtherStudentMessages.fromJson(dynamic json) {
_replyID = json['ReplyID'];
_repliedBy = json['RepliedBy'];
_replyMessage = json['ReplyMessage'];
}
String? _replyID;
String? _repliedBy;
String? _replyMessage;
OtherStudentMessages copyWith({ String? replyID,
String? repliedBy,
String? replyMessage,
}) => OtherStudentMessages( replyID: replyID ?? _replyID,
repliedBy: repliedBy ?? _repliedBy,
replyMessage: replyMessage ?? _replyMessage,
);
String? get replyID => _replyID;
String? get repliedBy => _repliedBy;
String? get replyMessage => _replyMessage;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['ReplyID'] = _replyID;
map['RepliedBy'] = _repliedBy;
map['ReplyMessage'] = _replyMessage;
return map;
}
}
And here is the JSON response from the API. (with one entry)
{
"CourseLessonDetailsData": [
{
"request_status": "Successful",
"DiscussionDetails": [
{
"DiscussionsMessages": [
{
"MessageID": "301",
"ID": "48",
"StudentName": "Person Name",
"Message": "This is from Message",
"ReplyMessage": "This is a Reply Message",
"OtherStudentMessages": [
{
"ReplyID":"939",
"RepliedBy":"Reply Person",
"ReplyMessage":"resubmit means you can submit again if you want until the deadline is over"
}
]
}
]
}
]
}
]
}
I edited your code but could not test it out, please check it if it works.
You need to make a list variable that will hold all your paginated data. Then call your future and then after result is not null, add it to your list and change your loading status to false. After, use scrolls and scrollListener reaches max extent, change offset and call your api again and after result is not null, again add to your list.
class PaginatedScreen extends StatefulWidget {
const PaginatedScreen({Key? key}) : super(key: key);
#override
State<PaginatedScreen> createState() => _PaginatedScreenState();
}
class _PaginatedScreenState extends State<PaginatedScreen> {
final scrollController = ScrollController();
int offSetCurrent = 0;
bool hasMore = true;
bool isLoading = true;
List<PaginatedModel> listOfData = <PaginatedModel>[];
#override
void initState() async {
super.initState();
var result = await getDiscussion(offSetCurrent);
if (result != null) {
setState(() {
listOfData.add(result);
isLoading = false;
});
}
scrollController.addListener(() async {
if (scrollController.position.maxScrollExtent == scrollController.offset) {
offSetCurrent = offSetCurrent + 10;
setState(() {
isLoading = true;
});
var result = await getDiscussion(offSetCurrent);
setState(() {
listOfData.add(result!);
isLoading = false;
});
}
});
}
#override
void dispose(){
scrollController.dispose();
super.dispose();
}
Future<PaginatedModel?> getDiscussion(offSetCurrent) async {
// if (isLoading) return;
// isLoading = true;
SharedPreferences sp = await SharedPreferences.getInstance();
var parameters = {
'RangeFrom':offSetCurrent.toString(),
'AccessToken':sp.getString('AccessToken'),
'DiscussionID':'22848',
};
var urlfetch = Uri(
scheme: "https",
host: baseUrl,
path: discussionAPIPath,
queryParameters: parameters,
);
try {
http.Response response = await http.get(Uri.parse(urlfetch.toString()));
var data = jsonDecode(response.body.toString());
var snapshot = PaginatedModel.fromJson(data);
var itemsTotal = snapshot.courseLessonDetailsData!.first.discussionDetails!.first.discussionsMessages!.length;
if (itemsTotal < 10){
setState((){
hasMore = false;
});
}
print(data);
print('Discussion API HIT with offset $offSetCurrent');
// isLoading = false;
if (response.statusCode == 200) {
return PaginatedModel.fromJson(data);
}
else {
print(response.statusCode);
return null;
}
}
catch (e) {
print(e.toString());
rethrow;
// return null;
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: isLoading
? CircularProgressIndicator()
: ListView.builder(
itemCount: listOfData.length,
itemBuilder: (context, index) {
//do your widget building here
// do whatever you did in your future builder here
return Text(listOfData[index].courseLessonDetailsData![0].requestStatus!);
},
),
// body: FutureBuilder(
// future: getDiscussion(offSetCurrent),
// builder: (dCtx, dSnapshot){
// if (dSnapshot.hasData){
// var itemCount = dSnapshot.data!.courseLessonDetailsData!.first.discussionDetails!.first.discussionsMessages!.length;
// return ListView.builder(
// controller: scrollController,
// shrinkWrap: true,
// itemCount: itemCount + 1,
// itemBuilder: (context, idx){
// if (idx < itemCount){
// return Column(
// children: List<Widget>.generate(dSnapshot.data!.courseLessonDetailsData!.first.discussionDetails!.length, (i) => Container(
// margin: const EdgeInsets.all(10),
// child: Column(
// children: [
// Html(data: dSnapshot.data!.courseLessonDetailsData!.first.discussionDetails!.first.discussionsMessages![idx].message.toString()),
// ],
// ),
// ))
// );
// }
// else {
// return Padding(
// padding: EdgeInsets.symmetric(vertical: 32),
// child: Center(
// child: hasMore? CircularProgressIndicator() : Text('No More Data'),
// ),
// );
// }
// }
// );
// }
// else {
// return const Center(
// child: CircularProgressIndicator(),
// );
// }
// }
// ),
);
}
}

type 'Null' is not a subtype of type 'List<dynamic>' in type cast in flutter

I am trying to fetch image from an api. For that I am using http package for flutter. I created Model View Controller pattern to arrange the structure of the project. Here is the api link and response:
https://wrestlingworld.co/wp-json/wp/v2/posts/128354
Response =>
[{"id":128640,"date":"2022-11-04T15:09:58","date_gmt":"2022-11-04T09:39:58","guid":{"rendered":"https:\/\/wrestlingworld.co\/?p=128640"},"modified":"2022-11-04T15:10:04","modified_gmt":"2022-11-04T09:40:04","slug":"impact-knockouts-tag-team-championship-match-announced-for-over-drive-2022","status":"publish","type":"post","link":"https:\/\/wrestlingworld.co\/news\/impact-knockouts-tag-team-championship-match-announced-for-over-drive-2022","title":{"rendered":"Impact Knockouts Tag Team Championship Match Announced for Over Drive"},"content":{"rendered":"\n<p>Impact Knockouts Tag Team Championships will be on the line at Over Drive on November 18th. It has <a href=\"https:\/\/impactwrestling.com\/2022\/11\/03\/tasha-steelz-savannah-evans-look-to-topple-the-death-dollz-in-knockouts-world-tag-team-title-showdown-at-over-drive\/\" target=\"_blank\" rel=\"noreferrer noopener nofollow\">been announced<\/a> that Death Dollz (Taya Valkyrie and Jessicka) will be defending their titles against Tasha Steelz and Savannah
Here is my model:
class NewsModel {
int? id;
String? date;
String? slug;
String? status;
Title? title;
Title? content;
List<OgImage>? ogImage;
int? author;
NewsModel(
{this.id,
this.date,
this.slug,
this.status,
this.title,
this.content,
this.ogImage,
this.author});
NewsModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
date = json['date'];
slug = json['slug'];
status = json['status'];
title = json['title'] != null ? new Title.fromJson(json['title']) : null;
content =
json['content'] != null ? new Title.fromJson(json['content']) : null;
if (json['og_image'] != null) {
ogImage = <OgImage>[];
json['og_image'].forEach((v) {
ogImage!.add(new OgImage.fromJson(v));
});
}
author = json['author'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['date'] = this.date;
data['slug'] = this.slug;
data['status'] = this.status;
if (this.title != null) {
data['title'] = this.title!.toJson();
}
if (this.content != null) {
data['content'] = this.content!.toJson();
}
if (this.ogImage != null) {
data['og_image'] = this.ogImage!.map((v) => v.toJson()).toList();
}
data['author'] = this.author;
return data;
}
}
class Title {
String? rendered;
Title({this.rendered});
Title.fromJson(Map<String, dynamic> json) {
rendered = json['rendered'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['rendered'] = this.rendered;
return data;
}
}
class OgImage {
String? url;
OgImage({this.url});
OgImage.fromJson(Map<String, dynamic> json) {
url = json['url'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['url'] = this.url;
return data;
}
}
Here you can see OgImage is a list So I created a card and tried this code:
final int id;
final String title;
final String description;
final List<dynamic> img;
const NewsCard({
required this.id,
required this.title,
required this.description,
required this.img,
});
ListView.builder(
itemCount: img.length,
itemBuilder: (context, item){
return Image.network(
img[item],
height: 120,
width: double.infinity
);
},
),
Here is the front end code where I am passing value :
Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
physics: const ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: allNews.length,
itemBuilder: (context, i) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: NewsCard(
id: allNews[i].id as int,
title: allNews[i].title!.rendered!,
description: allNews[i].content!.rendered!,
img: allNews[i].ogImage?[0].url as List<dynamic>,
),
);
}),),
Here is my controller :
Future<bool> getNews() async {
var url = Uri.parse(urlnews);
// var token = storage.getItem('token');
try {
http.Response response = await http.get(url);
print(response.body);
var data = json.decode(response.body) as List;
// print(data);
List<NewsModel> temp = [];
data.forEach((element) {
NewsModel product = NewsModel.fromJson(element);
temp.add(product);
});
_news = temp;
notifyListeners();
return true;
} catch (e) {
print(e);
return false;
}
}
List<NewsModel> get allNews {
return [..._news];
}
This code has errors I mentioned in the title already. Here I have a qustion like how can I pass list value inside the card. What is right way to fetch lists of image inside a widget.
There are a few issues with your code:
1. In your NewsModel class file, you're mapping it all wrong.
You're mapping json['og_image'] to a List, while json['og_image'] doesn't exist in the first place. If you see the JSON response, instead it's within the json['yoast_head_json'] key. So, instead of json['og_image'] you need to do json['yoast_head_json']['og_image'].
Change:
if (json['og_image'] != null) {
ogImage = <OgImage>[];
json['og_image'].forEach((v) {
ogImage!.add(new OgImage.fromJson(v));
});
}
to:
if (json['yoast_head_json'] != null &&
json['yoast_head_json']['og_image'] != null) {
ogImage = <OgImage>[];
json['yoast_head_json']['og_image'].forEach((v) {
ogImage!.add(OgImage.fromJson(v));
});
2. In your frontend part, you're trying to cast a nullable type of list allNews[i].ogImage?[0].url as List<dynamic> to List<dynamic>, which will throw exception in case the list is NULL which is in your case.
so, instead of:
img: allNews[i].ogImage?[0].url as List<dynamic>
do:
img: allNews[i].ogImage ?? []
3. Finally, in your NewsCard class:
Change:
Image.network(
img[item],
...
);
to
Image.network(
img[item].url,
...
);
Enjoy :)

flutter, how to compare the argument passed (id) equal an element.id ? using getx package

I have Categories, and each category contains multiple and different subcategories.
I passed the Id of Categories to the other screen.
First Screen:
onTap: (() => Get.to(const CategoryDetails(), arguments: {
"id":" ${categoriesController.cat!.elementAt(i).sId.toString()} ", })),
ArgumentController
import 'package:get/get.dart';
class ArgumentController extends GetxController {
String? id;
#override
void onInit() {
id = Get.arguments['id'];
super.onInit();
}
}
View File
class _CategoryDetailsState extends State<CategoryDetails> {
int selectedCategoryIndex = 0;
CategoriesController categoriesController = Get.put(CategoriesController());
#override
void initState() {
super.initState();
categoriesController.getCategoriesFromApi();
}
#override
Widget build(BuildContext context) {
ArgumentController controller = Get.put(ArgumentController());
debugPrint(controller.id);
return Scaffold(
appBar: AppBar(
title: const Text("Category Details"),
),
body: Column(
children: [
Text("${controller.id}"),
const Text("data"),
ListView.builder(itemBuilder: (context, index) {
return Column(
children: [
Text(categoriesController.cat!
.elementAt(index)
.subcategories!
.elementAt(selectedCategoryIndex)
.name
.toString()),
],
);
})
],
),
);
}
}
Controller file:
import 'dart:convert';
import 'dart:io';
import 'package:get/get.dart';
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import '../model/categoriesmodel.dart' as categories_model;
class CategoriesController extends GetxController {
Iterable<categories_model.Response>? cat;
var isDataLoading = false.obs;
getCategoriesFromApi() async {
try {
isDataLoading(true);
http.Response response = await http.post(
Uri.tryParse('-----')!,
headers: {
HttpHeaders.authorizationHeader: '-------',
});
if (response.statusCode == 200) {
var result = jsonDecode(response.body);
cat = categories_model.Categories.fromJson(result).response;
} else {}
} catch (e) {
debugPrint("Error while getting Data $e");
} finally {
isDataLoading(false);
}
}
}
Categoriesmodel file
class Categories {
String? status;
List<Response>? response;
Categories({this.status, this.response});
Categories.fromJson(Map<String, dynamic> json) {
status = json['status'];
if (json['response'] != null) {
response = <Response>[];
json['response'].forEach((v) {
response!.add(Response.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['status'] = status;
if (response != null) {
data['response'] = response!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Response {
String? sId;
String? name;
bool? isForAccessories;
String? slug;
List<void>? liveTranslations;
String? icon;
String? logo;
int? itemsCount;
String? lang;
List<Subcategories>? subcategories;
Response(
{this.sId,
this.name,
this.isForAccessories,
this.slug,
this.liveTranslations,
this.icon,
this.logo,
this.itemsCount,
this.lang,
this.subcategories});
Response.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
name = json['name'];
isForAccessories = json['isForAccessories'];
slug = json['slug'];
// if (json['liveTranslations'] != null) {
// liveTranslations = <Null>[];
// json['liveTranslations'].forEach((v) {
// liveTranslations!.add(Null.fromJson(v));
// });
// }
icon = json['icon'];
logo = json['logo'];
itemsCount = json['itemsCount'];
lang = json['lang'];
if (json['subcategories'] != null) {
subcategories = <Subcategories>[];
json['subcategories'].forEach((v) {
subcategories!.add(Subcategories.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['_id'] = sId;
data['name'] = name;
data['isForAccessories'] = isForAccessories;
data['slug'] = slug;
// if (liveTranslations != null) {
// data['liveTranslations'] =
// liveTranslations!.map((v) => v.toJson()).toList();
// }
data['icon'] = icon;
data['logo'] = logo;
data['itemsCount'] = itemsCount;
data['lang'] = lang;
if (subcategories != null) {
data['subcategories'] =
subcategories!.map((v) => v.toJson()).toList();
}
return data;
}
}
class Subcategories {
String? sId;
String? name;
bool? isForAccessories;
String? slug;
List<void>? liveTranslations;
int? itemsCount;
String? lang;
Subcategories(
{this.sId,
this.name,
this.isForAccessories,
this.slug,
this.liveTranslations,
this.itemsCount,
this.lang});
Subcategories.fromJson(Map<String, dynamic> json) {
sId = json['_id'];
name = json['name'];
isForAccessories = json['isForAccessories'];
slug = json['slug'];
// if (json['liveTranslations'] != null) {
// liveTranslations = <Null>[];
// json['liveTranslations'].forEach((v) {
// liveTranslations!.add(Null.fromJson(v));
// });
// }
itemsCount = json['itemsCount'];
lang = json['lang'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['_id'] = sId;
data['name'] = name;
data['isForAccessories'] = isForAccessories;
data['slug'] = slug;
// if (liveTranslations != null) {
// data['liveTranslations'] =
// liveTranslations!.map((v) => v.toJson()).toList();
// }
data['itemsCount'] = itemsCount;
data['lang'] = lang;
return data;
}
}
The problem is in selectedCategoryIndex, how to express that
selectedCategoryIndex == categoriesController.Where((element) => element.sid == the argument passed);
note that it's not acceptable categoriesController.Where..
I just assumed your question to be what I think and posting this solution.
selectedCategoryIndex ==
categoriesController.cat.singleWhere((element) => element.id == id).sId;

type 'List<dynamic>' is not a subtype of type 'String'

It contains lots of list and nested objects. I need to display all the DishName from the json file
Json URL adress : Json address!! Check this out
i wanted to display the DishName in to my app in which there are lots of dishname in the json list.
i parsed the json file using instantly parse json website.
But now i dont know how to implent it on my app
code i wrote :
body: Container(
child: Center(
child: FutureBuilder(
future:
DefaultAssetBundle.of(context).loadString('jsons/data.json'),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
var myData = jsonDecode(snapshot.data);
final welcome = welcomeFromJson(myData);
print(myData.length);
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return Card(
child: ListTile(
title: Text(welcome[index]
.tableMenuList[index]
.categoryDishes[index]
.dishName),
));
},
itemCount: myData == null ? 0 : myData.length,
);
},
),
),
),
i am getting error : type 'List' is not a subtype of type 'String'
this is the json class:-
// To parse this JSON data, do
//
// final welcome = welcomeFromJson(jsonString);
import 'dart:convert';
List<Welcome> welcomeFromJson(String str) =>
List<Welcome>.from(json.decode(str).map((x) => Welcome.fromJson(x)));
String welcomeToJson(List<Welcome> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Welcome {
String restaurantId;
String restaurantName;
String restaurantImage;
String tableId;
String tableName;
String branchName;
String nexturl;
List<TableMenuList> tableMenuList;
Welcome({
this.restaurantId,
this.restaurantName,
this.restaurantImage,
this.tableId,
this.tableName,
this.branchName,
this.nexturl,
this.tableMenuList,
});
factory Welcome.fromJson(Map<String, dynamic> json) => Welcome(
restaurantId: json["restaurant_id"],
restaurantName: json["restaurant_name"],
restaurantImage: json["restaurant_image"],
tableId: json["table_id"],
tableName: json["table_name"],
branchName: json["branch_name"],
nexturl: json["nexturl"],
tableMenuList: List<TableMenuList>.from(
json["table_menu_list"].map((x) => TableMenuList.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"restaurant_id": restaurantId,
"restaurant_name": restaurantName,
"restaurant_image": restaurantImage,
"table_id": tableId,
"table_name": tableName,
"branch_name": branchName,
"nexturl": nexturl,
"table_menu_list":
List<dynamic>.from(tableMenuList.map((x) => x.toJson())),
};
}
class TableMenuList {
String menuCategory;
String menuCategoryId;
String menuCategoryImage;
String nexturl;
List<CategoryDish> categoryDishes;
TableMenuList({
this.menuCategory,
this.menuCategoryId,
this.menuCategoryImage,
this.nexturl,
this.categoryDishes,
});
factory TableMenuList.fromJson(Map<String, dynamic> json) => TableMenuList(
menuCategory: json["menu_category"],
menuCategoryId: json["menu_category_id"],
menuCategoryImage: json["menu_category_image"],
nexturl: json["nexturl"],
categoryDishes: List<CategoryDish>.from(
json["category_dishes"].map((x) => CategoryDish.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"menu_category": menuCategory,
"menu_category_id": menuCategoryId,
"menu_category_image": menuCategoryImage,
"nexturl": nexturl,
"category_dishes":
List<dynamic>.from(categoryDishes.map((x) => x.toJson())),
};
}
class AddonCat {
String addonCategory;
String addonCategoryId;
int addonSelection;
String nexturl;
List<CategoryDish> addons;
AddonCat({
this.addonCategory,
this.addonCategoryId,
this.addonSelection,
this.nexturl,
this.addons,
});
factory AddonCat.fromJson(Map<String, dynamic> json) => AddonCat(
addonCategory: json["addon_category"],
addonCategoryId: json["addon_category_id"],
addonSelection: json["addon_selection"],
nexturl: json["nexturl"],
addons: List<CategoryDish>.from(
json["addons"].map((x) => CategoryDish.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"addon_category": addonCategory,
"addon_category_id": addonCategoryId,
"addon_selection": addonSelection,
"nexturl": nexturl,
"addons": List<dynamic>.from(addons.map((x) => x.toJson())),
};
}
class CategoryDish {
String dishId;
String dishName;
double dishPrice;
String dishImage;
DishCurrency dishCurrency;
int dishCalories;
String dishDescription;
bool dishAvailability;
int dishType;
String nexturl;
List<AddonCat> addonCat;
CategoryDish({
this.dishId,
this.dishName,
this.dishPrice,
this.dishImage,
this.dishCurrency,
this.dishCalories,
this.dishDescription,
this.dishAvailability,
this.dishType,
this.nexturl,
this.addonCat,
});
factory CategoryDish.fromJson(Map<String, dynamic> json) => CategoryDish(
dishId: json["dish_id"],
dishName: json["dish_name"],
dishPrice: json["dish_price"].toDouble(),
dishImage: json["dish_image"],
dishCurrency: dishCurrencyValues.map[json["dish_currency"]],
dishCalories: json["dish_calories"],
dishDescription: json["dish_description"],
dishAvailability: json["dish_Availability"],
dishType: json["dish_Type"],
nexturl: json["nexturl"] == null ? null : json["nexturl"],
addonCat: json["addonCat"] == null
? null
: List<AddonCat>.from(
json["addonCat"].map((x) => AddonCat.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"dish_id": dishId,
"dish_name": dishName,
"dish_price": dishPrice,
"dish_image": dishImage,
"dish_currency": dishCurrencyValues.reverse[dishCurrency],
"dish_calories": dishCalories,
"dish_description": dishDescription,
"dish_Availability": dishAvailability,
"dish_Type": dishType,
"nexturl": nexturl == null ? null : nexturl,
"addonCat": addonCat == null
? null
: List<dynamic>.from(addonCat.map((x) => x.toJson())),
};
}
enum DishCurrency { SAR }
final dishCurrencyValues = EnumValues({"SAR": DishCurrency.SAR});
class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}
I personally use this one for generating dart classes from JSON https://javiercbk.github.io/json_to_dart/
From my experience most of these automatic class builders are flawed to some extent and it is good practice to go over the generated dart manually. Or try your luck and walk the stack trace to see where parsing failed (usually when handling int and double from what I've seen).
Anyhow back to your problem, from looking at your code I see you are misusing indexes and generally having problems with json data structure:
title: Text(welcome[index]
.tableMenuList[index]
.categoryDishes[index]
.dishName),
The code above can easily throw "RangeError (index): Invalid value: Not in range..." (example if welcome[ 2 ] has only 1 tableMenuList). Even if all those arrays above are somehow the same length you would still not get the expected result.. The list would end up showing you 1st meal from the 1st menu list and 1st category dish, then next one would be 2nd meal from the 2nd menu and the 2nd restaurant.
Also because of the same reason as above the following code isn't enough:
itemCount: myData == null ? 0 : myData.length,
You need to have an itemCount for each of those lists you are using.
I've modified your code to work with the given JSON and changed a few things, in the end it looks like this.
I'm posting my source bellow, hopefully it will make things clearer for you:
pubspec.yaml
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^0.1.2
http: any
welcome_model.dart
class Welcome {
String restaurantId;
String restaurantName;
String restaurantImage;
String tableId;
String tableName;
String branchName;
String nexturl;
List<TableMenuList> tableMenuList;
Welcome(
{this.restaurantId,
this.restaurantName,
this.restaurantImage,
this.tableId,
this.tableName,
this.branchName,
this.nexturl,
this.tableMenuList});
Welcome.fromJson(Map<String, dynamic> json) {
restaurantId = json['restaurant_id'];
restaurantName = json['restaurant_name'];
restaurantImage = json['restaurant_image'];
tableId = json['table_id'];
tableName = json['table_name'];
branchName = json['branch_name'];
nexturl = json['nexturl'];
if (json['table_menu_list'] != null) {
tableMenuList = new List<TableMenuList>();
json['table_menu_list'].forEach((v) {
tableMenuList.add(new TableMenuList.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['restaurant_id'] = this.restaurantId;
data['restaurant_name'] = this.restaurantName;
data['restaurant_image'] = this.restaurantImage;
data['table_id'] = this.tableId;
data['table_name'] = this.tableName;
data['branch_name'] = this.branchName;
data['nexturl'] = this.nexturl;
if (this.tableMenuList != null) {
data['table_menu_list'] =
this.tableMenuList.map((v) => v.toJson()).toList();
}
return data;
}
}
class TableMenuList {
String menuCategory;
String menuCategoryId;
String menuCategoryImage;
String nexturl;
List<CategoryDishes> categoryDishes;
TableMenuList(
{this.menuCategory,
this.menuCategoryId,
this.menuCategoryImage,
this.nexturl,
this.categoryDishes});
TableMenuList.fromJson(Map<String, dynamic> json) {
menuCategory = json['menu_category'];
menuCategoryId = json['menu_category_id'];
menuCategoryImage = json['menu_category_image'];
nexturl = json['nexturl'];
if (json['category_dishes'] != null) {
categoryDishes = new List<CategoryDishes>();
json['category_dishes'].forEach((v) {
categoryDishes.add(new CategoryDishes.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['menu_category'] = this.menuCategory;
data['menu_category_id'] = this.menuCategoryId;
data['menu_category_image'] = this.menuCategoryImage;
data['nexturl'] = this.nexturl;
if (this.categoryDishes != null) {
data['category_dishes'] =
this.categoryDishes.map((v) => v.toJson()).toList();
}
return data;
}
}
class CategoryDishes {
String dishId;
String dishName;
double dishPrice;
String dishImage;
String dishCurrency;
double dishCalories;
String dishDescription;
bool dishAvailability;
int dishType;
String nexturl;
List<AddonCat> addonCat;
CategoryDishes(
{this.dishId,
this.dishName,
this.dishPrice,
this.dishImage,
this.dishCurrency,
this.dishCalories,
this.dishDescription,
this.dishAvailability,
this.dishType,
this.nexturl,
this.addonCat});
CategoryDishes.fromJson(Map<String, dynamic> json) {
dishId = json['dish_id'];
dishName = json['dish_name'];
dishPrice = json['dish_price'];
dishImage = json['dish_image'];
dishCurrency = json['dish_currency'];
dishCalories = json['dish_calories'];
dishDescription = json['dish_description'];
dishAvailability = json['dish_Availability'];
dishType = json['dish_Type'];
nexturl = json['nexturl'];
if (json['addonCat'] != null) {
addonCat = new List<AddonCat>();
json['addonCat'].forEach((v) {
addonCat.add(new AddonCat.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['dish_id'] = this.dishId;
data['dish_name'] = this.dishName;
data['dish_price'] = this.dishPrice;
data['dish_image'] = this.dishImage;
data['dish_currency'] = this.dishCurrency;
data['dish_calories'] = this.dishCalories;
data['dish_description'] = this.dishDescription;
data['dish_Availability'] = this.dishAvailability;
data['dish_Type'] = this.dishType;
data['nexturl'] = this.nexturl;
if (this.addonCat != null) {
data['addonCat'] = this.addonCat.map((v) => v.toJson()).toList();
}
return data;
}
}
class AddonCat {
String addonCategory;
String addonCategoryId;
int addonSelection;
String nexturl;
List<Addons> addons;
AddonCat(
{this.addonCategory,
this.addonCategoryId,
this.addonSelection,
this.nexturl,
this.addons});
AddonCat.fromJson(Map<String, dynamic> json) {
addonCategory = json['addon_category'];
addonCategoryId = json['addon_category_id'];
addonSelection = json['addon_selection'];
nexturl = json['nexturl'];
if (json['addons'] != null) {
addons = new List<Addons>();
json['addons'].forEach((v) {
addons.add(new Addons.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['addon_category'] = this.addonCategory;
data['addon_category_id'] = this.addonCategoryId;
data['addon_selection'] = this.addonSelection;
data['nexturl'] = this.nexturl;
if (this.addons != null) {
data['addons'] = this.addons.map((v) => v.toJson()).toList();
}
return data;
}
}
class Addons {
String dishId;
String dishName;
double dishPrice;
String dishImage;
String dishCurrency;
double dishCalories;
String dishDescription;
bool dishAvailability;
int dishType;
Addons(
{this.dishId,
this.dishName,
this.dishPrice,
this.dishImage,
this.dishCurrency,
this.dishCalories,
this.dishDescription,
this.dishAvailability,
this.dishType});
Addons.fromJson(Map<String, dynamic> json) {
dishId = json['dish_id'];
dishName = json['dish_name'];
dishPrice = json['dish_price'];
dishImage = json['dish_image'];
dishCurrency = json['dish_currency'];
dishCalories = json['dish_calories'];
dishDescription = json['dish_description'];
dishAvailability = json['dish_Availability'];
dishType = json['dish_Type'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['dish_id'] = this.dishId;
data['dish_name'] = this.dishName;
data['dish_price'] = this.dishPrice;
data['dish_image'] = this.dishImage;
data['dish_currency'] = this.dishCurrency;
data['dish_calories'] = this.dishCalories;
data['dish_description'] = this.dishDescription;
data['dish_Availability'] = this.dishAvailability;
data['dish_Type'] = this.dishType;
return data;
}
}
welcome_page.dart
import 'package:flutter/material.dart';
import 'welcome_model.dart';
import 'dart:async';
import 'dart:io';
import 'dart:convert';
import 'package:http/http.dart' as http;
class WelcomePage extends StatefulWidget {
#override
_WelcomePageState createState() => new _WelcomePageState();
}
class _WelcomePageState extends State<WelcomePage> {
List<Welcome> welcomeList;
bool isLoading = true;
int selectedRestaurantIndex = 0;
String titleString = "Restaurant";
#override
void initState() {
super.initState();
_fetchData();
}
#override
void setState(fn) {
if(mounted){
super.setState(fn);
}
}
#override
void dispose() {
super.dispose();
}
_fetchData() async{
setState(() {
isLoading = true;
});
// String url = Uri.encodeFull("http://www.mocky.io/v2/5dfccffc310000efc8d2c1ad"); // original json has only one restaurant
// the one bellow has 3 restaurants,
// 1st one was left untouched,
// 2nd one (Steak house) has only "From The Barnyard" and "Fast Food" menu types
// 3rd one (Bistro cafe) has only "Fresh From The Sea" and "Fast Food" menu types
String url = Uri.encodeFull("http://www.mocky.io/v2/5e4aa68c2f0000690097d3f6");
var parsedJson;
try {
http.Response response = await http.get(url).
timeout(Duration(seconds: 10));
if (response.statusCode == 200) {
if (response.bodyBytes != null) {
parsedJson = json.decode(utf8.decode(response.bodyBytes));
}
} else {
print('RESPONSE CODE != 200 !');
}
} on TimeoutException catch (e) {
print('Error: $e');
} on SocketException catch (e) {
print('Error: $e');
} on Error catch (e) {
print('Error: $e');
}
if(parsedJson!=null){
if(parsedJson.length>0){
welcomeList = new List<Welcome>();
for(int i=0; i<parsedJson.length; i++) {
try {
welcomeList.add(Welcome.fromJson(parsedJson[i]));
} catch (e, s){
print('Eroor parsing from JSON! For # $i');
print('Error: $e');
print('Stacktrace: $s');
}
}
if(welcomeList[0]!=null && welcomeList[0].restaurantName!=null) {
titleString = welcomeList[0].restaurantName;
}
}
}
setState(() {
isLoading = false;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
iconTheme: IconThemeData(
color: Colors.white,
),
title: Text(titleString),
centerTitle: true,
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text("Select a restaurant", style: TextStyle(color: Colors.white, fontSize: 28),textAlign: TextAlign.center,
),
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
),
),
(welcomeList!=null && welcomeList.length>0) ?
ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemCount: welcomeList.length,
itemBuilder: (BuildContext context, int index) {
return Padding(
padding: EdgeInsets.all(8),
child: RaisedButton(
onPressed: () {
setState(() {
selectedRestaurantIndex = index;
titleString = welcomeList[index].restaurantName.toString();
});
Navigator.pop(context);
},
padding: EdgeInsets.all(12),
child: Text(welcomeList[index].restaurantName.toString()),
)
);
;}
)
: Text("No restaurants loaded...")
]
)
),
body: (isLoading)
? Center(child: CircularProgressIndicator(),)
: Container(
child: Center(
child: ListView.builder(
itemBuilder: (BuildContext context, int index1) {
return Card(
child: ListTile(
subtitle: Text(welcomeList[selectedRestaurantIndex].tableMenuList[index1].menuCategory.toString()),
title: ListView.builder(
shrinkWrap: true,
physics: ClampingScrollPhysics(),
itemBuilder: (BuildContext context, int index2) {
return Card(
child: ListTile(
title: Text(welcomeList[selectedRestaurantIndex].tableMenuList[index1].categoryDishes[index2].dishName.toString()),
));
},
itemCount: (welcomeList[selectedRestaurantIndex].tableMenuList[index1] == null || welcomeList[selectedRestaurantIndex].tableMenuList[index1].categoryDishes == null) ? 0 : (welcomeList[selectedRestaurantIndex].tableMenuList[index1].categoryDishes.length) ,)
)
);
},
itemCount: (welcomeList == null || welcomeList[selectedRestaurantIndex] == null || welcomeList[selectedRestaurantIndex].tableMenuList == null) ? 0 : (welcomeList[selectedRestaurantIndex].tableMenuList.length) ,
)
),
),
);
}
}
JSON with 3 restaurants here or here.