RangeError (index): Invalid value: Valid value range is empty: 0 嵌套 Json in Flutter
RangeError (index): Invalid value: Valid value range is empty: 0 Nested Json in Flutter
我正在尝试使用 flutter_bloc
库模式获取 api,我成功地获取了数据,但问题在下面,我首先提到了 json
数据两个元素在 restaurant_branch
中有一个空的 []
数组,最后一个(第三个)元素在 restaurant_branch
中有数据,这导致空点异常 ("RangeError (index): Invalid value: Valid HomePage.dart
(在文本小部件中)代码中的值范围为空:0")。那么如何防止这个问题。
json data
{
"message": "restaurants returned",
"data": [
{
"id": 40,
"name": "Arnulfo",
"aboutUs": "Voluptate omnis consequatur saepe doloribus tempore quia error. Praesentium esse blanditiis illo eos qui et deserunt rerum. Velit provident aliquam eveniet qui corporis. Culpa molestiae incidunt eaque unde id tempore. Tenetur ducimus amet hic sunt et.",
"phoneNumber": 58432,
"address": "70990 Stark Streets",
"latitude": "73.6105",
"longitude": "-95.9985",
"image": "https://cdn.fakercloud.com/avatars/matthewkay__128.jpg",
"countryCode": "VE ",
"restaurantRegisterDocument": "Est qui voluptatem.",
"isDeleted": false,
"createdAt": "2021-09-04T20:24:06.310Z",
"updatedAt": "2021-09-04T20:24:06.310Z",
"restaurantTypeId": 1,
"categoryId": 1,
"userId": 3,
"user": {
"id": 3,
"firstName": "Marisa",
"lastName": "Mills",
"email": "Darrick_Reichert94@gmail.com",
"phoneNumber": "90428",
"address": "870 Guadalupe River",
"gender": "female",
"language": "ar",
"createdAt": "2021-09-04T20:14:05.939Z",
"updatedAt": "2021-09-04T20:14:05.939Z"
},
"restaurant_branch": []
},
{
"id": 39,
"name": "Maynard",
"aboutUs": "Sunt veniam numquam perferendis consequatur. Accusantium mollitia nemo odit nihil alias dolor. Voluptatibus officia consectetur nihil. Voluptas eligendi aliquam.",
"phoneNumber": 93756,
"address": "38743 Freda Green",
"latitude": "-50.3143",
"longitude": "114.4596",
"image": "https://cdn.fakercloud.com/avatars/omnizya_128.jpg",
"countryCode": "PH ",
"restaurantRegisterDocument": "Voluptatem et expedita rerum eos eaque nihil et culpa.",
"isDeleted": false,
"createdAt": "2021-09-04T20:24:06.309Z",
"updatedAt": "2021-09-04T20:24:06.309Z",
"restaurantTypeId": 1,
"categoryId": 4,
"userId": 6,
"user": {
"id": 6,
"firstName": "Layne",
"lastName": "Turcotte",
"email": "Jayson_Rice@yahoo.com",
"phoneNumber": "98802",
"address": "659 Trudie Keys",
"gender": "male",
"language": "ar",
"createdAt": "2021-09-04T20:14:05.939Z",
"updatedAt": "2021-09-04T20:14:05.939Z"
},
"restaurant_branch": []
},
{
"id": 10,
"name": "Kaden",
"aboutUs": "Et dolore cumque et iusto vel qui iste facere. Quia sed minima. Porro eos inventore qui voluptas animi voluptates fuga commodi magnam. Voluptas eligendi sunt et fugiat repudiandae asperiores maxime sit. Impedit exercitationem laudantium error autem modi voluptas et. Vitae ut non voluptatem culpa eos quae occaecati.",
"phoneNumber": 94005,
"address": "920 Sawayn Street",
"latitude": "-69.1354",
"longitude": "-176.2695",
"image": "https://cdn.fakercloud.com/avatars/daniloc_128.jpg",
"countryCode": "PW ",
"restaurantRegisterDocument": "Fugiat ut autem et voluptates aut quisquam distinctio qui aut.",
"isDeleted": true,
"createdAt": "2021-09-04T20:14:06.352Z",
"updatedAt": "2021-09-04T20:14:06.352Z",
"restaurantTypeId": 6,
"categoryId": 3,
"userId": 4,
"user": {
"id": 4,
"firstName": "Santiago",
"lastName": "Kling",
"email": "Yoshiko.Block@yahoo.com",
"phoneNumber": "4436",
"address": "809 Earlene Square",
"gender": "female",
"language": "ar",
"createdAt": "2021-09-04T20:14:05.939Z",
"updatedAt": "2021-09-04T20:14:05.939Z"
},
"restaurant_branch": [
{
"id": 4,
"name": "Audreanne",
"description": "Kreiger",
"email": "Waylon.Osinski@yahoo.com",
"phoneNumber": 95645,
"address": "91601 Clifford Bypass",
"country_code": "SM ",
"image": "https://cdn.fakercloud.com/avatars/nicolasfolliot_128.jpg",
"latitude": "-42.0925",
"longitude": "-111.4455",
"workingHours": "Carolina AI Fresh",
"workingDays": "Friday",
"offDays": "Thursday",
"locationAddress": "802 Hoppe Ranch",
"locationCity": "Diamond Bar",
"status": 2,
"hasParking": true,
"instruction": "Bogan",
"isActive": true,
"isDeleted": false,
"createdAt": "2021-09-04T20:14:07.204Z",
"updatedAt": "2021-09-04T20:14:07.204Z",
"restaurantId": 10,
"cityId": 6,
"districtId": 1,
"feedbacks": [
{
"id": 39,
"comment": "International Communications Officer",
"star": 3,
"createdAt": "2021-09-04T20:24:07.433Z",
"updatedAt": "2021-09-04T20:24:07.433Z",
"customerId": 1,
"restaurantBranchId": 4
}
]
},
]
}
RecommendedForYouModel
class RecommendedForYouDataRestaurantBranchFeedbacks {
int? id;
String? comment;
int? star;
String? createdAt;
String? updatedAt;
int? customerId;
int? restaurantBranchId;
RecommendedForYouDataRestaurantBranchFeedbacks({
this.id,
this.comment,
this.star,
this.createdAt,
this.updatedAt,
this.customerId,
this.restaurantBranchId,
});
RecommendedForYouDataRestaurantBranchFeedbacks.fromJson(
Map<String, dynamic> json) {
id = json["id"]?.toInt();
comment = json["comment"]?.toString();
star = json["star"]?.toInt();
createdAt = json["createdAt"]?.toString();
updatedAt = json["updatedAt"]?.toString();
customerId = json["customerId"]?.toInt();
restaurantBranchId = json["restaurantBranchId"]?.toInt();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
data["comment"] = comment;
data["star"] = star;
data["createdAt"] = createdAt;
data["updatedAt"] = updatedAt;
data["customerId"] = customerId;
data["restaurantBranchId"] = restaurantBranchId;
return data;
}
}
class RecommendedForYouDataRestaurantBranch {
int? id;
String? name;
String? description;
String? email;
int? phoneNumber;
String? address;
String? countryCode;
String? image;
String? latitude;
String? longitude;
String? workingHours;
String? workingDays;
String? offDays;
String? locationAddress;
String? locationCity;
int? status;
bool? hasParking;
String? instruction;
bool? isActive;
bool? isDeleted;
String? createdAt;
String? updatedAt;
int? restaurantId;
int? cityId;
int? districtId;
List<RecommendedForYouDataRestaurantBranchFeedbacks?>? feedbacks;
RecommendedForYouDataRestaurantBranch({
this.id,
this.name,
this.description,
this.email,
this.phoneNumber,
this.address,
this.countryCode,
this.image,
this.latitude,
this.longitude,
this.workingHours,
this.workingDays,
this.offDays,
this.locationAddress,
this.locationCity,
this.status,
this.hasParking,
this.instruction,
this.isActive,
this.isDeleted,
this.createdAt,
this.updatedAt,
this.restaurantId,
this.cityId,
this.districtId,
this.feedbacks,
});
RecommendedForYouDataRestaurantBranch.fromJson(Map<String, dynamic> json) {
id = json["id"]?.toInt();
name = json["name"]?.toString();
description = json["description"]?.toString();
email = json["email"]?.toString();
phoneNumber = json["phoneNumber"]?.toInt();
address = json["address"]?.toString();
countryCode = json["country_code"]?.toString();
image = json["image"]?.toString();
latitude = json["latitude"]?.toString();
longitude = json["longitude"]?.toString();
workingHours = json["workingHours"]?.toString();
workingDays = json["workingDays"]?.toString();
offDays = json["offDays"]?.toString();
locationAddress = json["locationAddress"]?.toString();
locationCity = json["locationCity"]?.toString();
status = json["status"]?.toInt();
hasParking = json["hasParking"];
instruction = json["instruction"]?.toString();
isActive = json["isActive"];
isDeleted = json["isDeleted"];
createdAt = json["createdAt"]?.toString();
updatedAt = json["updatedAt"]?.toString();
restaurantId = json["restaurantId"]?.toInt();
cityId = json["cityId"]?.toInt();
districtId = json["districtId"]?.toInt();
if (json["feedbacks"] != null) {
final v = json["feedbacks"];
final arr0 = <RecommendedForYouDataRestaurantBranchFeedbacks>[];
v.forEach((v) {
arr0.add(RecommendedForYouDataRestaurantBranchFeedbacks.fromJson(v));
});
feedbacks = arr0;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
data["name"] = name;
data["description"] = description;
data["email"] = email;
data["phoneNumber"] = phoneNumber;
data["address"] = address;
data["country_code"] = countryCode;
data["image"] = image;
data["latitude"] = latitude;
data["longitude"] = longitude;
data["workingHours"] = workingHours;
data["workingDays"] = workingDays;
data["offDays"] = offDays;
data["locationAddress"] = locationAddress;
data["locationCity"] = locationCity;
data["status"] = status;
data["hasParking"] = hasParking;
data["instruction"] = instruction;
data["isActive"] = isActive;
data["isDeleted"] = isDeleted;
data["createdAt"] = createdAt;
data["updatedAt"] = updatedAt;
data["restaurantId"] = restaurantId;
data["cityId"] = cityId;
data["districtId"] = districtId;
if (feedbacks != null) {
final v = feedbacks;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data["feedbacks"] = arr0;
}
return data;
}
}
class RecommendedForYouDataUser {
int? id;
String? firstName;
String? lastName;
String? email;
String? phoneNumber;
String? address;
String? gender;
String? language;
String? createdAt;
String? updatedAt;
RecommendedForYouDataUser({
this.id,
this.firstName,
this.lastName,
this.email,
this.phoneNumber,
this.address,
this.gender,
this.language,
this.createdAt,
this.updatedAt,
});
RecommendedForYouDataUser.fromJson(Map<String, dynamic> json) {
id = json["id"]?.toInt();
firstName = json["firstName"]?.toString();
lastName = json["lastName"]?.toString();
email = json["email"]?.toString();
phoneNumber = json["phoneNumber"]?.toString();
address = json["address"]?.toString();
gender = json["gender"]?.toString();
language = json["language"]?.toString();
createdAt = json["createdAt"]?.toString();
updatedAt = json["updatedAt"]?.toString();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
data["firstName"] = firstName;
data["lastName"] = lastName;
data["email"] = email;
data["phoneNumber"] = phoneNumber;
data["address"] = address;
data["gender"] = gender;
data["language"] = language;
data["createdAt"] = createdAt;
data["updatedAt"] = updatedAt;
return data;
}
}
class RecommendedForYouData {
int? id;
String? name;
String? aboutUs;
int? phoneNumber;
String? address;
String? latitude;
String? longitude;
String? image;
String? countryCode;
String? restaurantRegisterDocument;
bool? isDeleted;
String? createdAt;
String? updatedAt;
int? restaurantTypeId;
int? categoryId;
int? userId;
RecommendedForYouDataUser? user;
List<RecommendedForYouDataRestaurantBranch?>? restaurantBranch;
RecommendedForYouData({
this.id,
this.name,
this.aboutUs,
this.phoneNumber,
this.address,
this.latitude,
this.longitude,
this.image,
this.countryCode,
this.restaurantRegisterDocument,
this.isDeleted,
this.createdAt,
this.updatedAt,
this.restaurantTypeId,
this.categoryId,
this.userId,
this.user,
this.restaurantBranch,
});
RecommendedForYouData.fromJson(Map<String, dynamic> json) {
id = json["id"]?.toInt();
name = json["name"]?.toString();
aboutUs = json["aboutUs"]?.toString();
phoneNumber = json["phoneNumber"]?.toInt();
address = json["address"]?.toString();
latitude = json["latitude"]?.toString();
longitude = json["longitude"]?.toString();
image = json["image"]?.toString();
countryCode = json["countryCode"]?.toString();
restaurantRegisterDocument = json["restaurantRegisterDocument"]?.toString();
isDeleted = json["isDeleted"];
createdAt = json["createdAt"]?.toString();
updatedAt = json["updatedAt"]?.toString();
restaurantTypeId = json["restaurantTypeId"]?.toInt();
categoryId = json["categoryId"]?.toInt();
userId = json["userId"]?.toInt();
user = (json["user"] != null)
? RecommendedForYouDataUser.fromJson(json["user"])
: null;
if (json["restaurant_branch"] != null) {
final v = json["restaurant_branch"];
final arr0 = <RecommendedForYouDataRestaurantBranch>[];
v.forEach((v) {
arr0.add(RecommendedForYouDataRestaurantBranch.fromJson(v));
});
restaurantBranch = arr0;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
data["name"] = name;
data["aboutUs"] = aboutUs;
data["phoneNumber"] = phoneNumber;
data["address"] = address;
data["latitude"] = latitude;
data["longitude"] = longitude;
data["image"] = image;
data["countryCode"] = countryCode;
data["restaurantRegisterDocument"] = restaurantRegisterDocument;
data["isDeleted"] = isDeleted;
data["createdAt"] = createdAt;
data["updatedAt"] = updatedAt;
data["restaurantTypeId"] = restaurantTypeId;
data["categoryId"] = categoryId;
data["userId"] = userId;
if (user != null) {
data["user"] = user!.toJson();
}
if (restaurantBranch != null) {
final v = restaurantBranch;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data["restaurant_branch"] = arr0;
}
return data;
}
}
class RecommendedForYou {
String? message;
List<RecommendedForYouData?>? data;
RecommendedForYou({
this.message,
this.data,
});
RecommendedForYou.fromJson(Map<String, dynamic> json) {
message = json["message"]?.toString();
if (json["data"] != null) {
final v = json["data"];
final arr0 = <RecommendedForYouData>[];
v.forEach((v) {
arr0.add(RecommendedForYouData.fromJson(v));
});
this.data = arr0;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["message"] = message;
if (this.data != null) {
final v = this.data;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data["data"] = arr0;
}
return data;
}
}
HomePage.dart
Container(
child: Padding(
padding:
const EdgeInsets.only(top: 20.0, left: 20.0, right: 20.0),
child: Container(
height: height,
child: BlocBuilder<RecommendedBloc, RecommendedState>(
builder: (context, state) {
if (state is LoadingRecommendedState) {
return Center(
child: PlatformCircularProgressIndicator());
} else if (state is LoadedRecommendedForYouState) {
return buildRecommendationRestaurant(state.data);
} else if (state is ErrorRecommendedState) {
return Center(child: Text(state.message));
}
return Container();
}),
),
),
),
Widget buildRecommendationRestaurant(List<RecommendedForYouData> data) {
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
child: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Card(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.only(top: 5.0, right: 5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Icon(
Icons.near_me,
size: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 5.0),
child: Text(
'5km',
style: TextStyle(fontSize: 10.0),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 5.0),
child: CachedNetworkImage(
imageUrl: data[index].image!,
fit: BoxFit.cover,
placeholder: (context, url) => Center(
child:
PlatformCircularProgressIndicator()),
errorWidget: (context, url, error) =>
Icon(Icons.error),
height:
MediaQuery.of(context).size.width * 0.18,
width:
MediaQuery.of(context).size.width * 0.18,
),
),
Padding(
padding: const EdgeInsets.only(
left: 10.0, right: 35.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
data[index].name!,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0),
),
Row(
children: [
Text(
'4.5',
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500),
),
Text(
'(${data[index].restaurantBranch![index]!.feedbacks!.length.toString()} RATING)', //Here on this line getting null because first element is []
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500),
)
],
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Row(
children: [
ImageIcon(
AssetImage(
'images/food-serving.png'),
size: 15.0,
),
Text(
'Italian Food - Steake',
style: TextStyle(fontSize: 12.0),
)
],
),
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Row(
children: [
Icon(
Icons.location_on_outlined,
size: 12.0,
color: TuxedoColor.greyColor,
),
Text(
'Riyadh',
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w600),
)
],
),
)
],
),
),
],
),
),
],
),
)),
),
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => DetailsPage(
id: data[index].id!,
)));
},
);
});
}
您还在为 restaurant_branch
数组使用父 listView 的 index
变量。由于 restaurant_branch
是一个不同的数组,如果您想在布局上有效地显示分支,您应该使用嵌套的 ListView。在你的情况下,如果每个 restaurant
没有多个分支,你可以像这样使用它
.......
Row(
children: [
Text(
'4.5',
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500),
),
Text(
'(${data[index].restaurantBranch![0]!.feedbacks!.length.toString()} RATING)', //Here on this line getting null because first element is []
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500),
)
],
),
......
我正在尝试使用 flutter_bloc
库模式获取 api,我成功地获取了数据,但问题在下面,我首先提到了 json
数据两个元素在 restaurant_branch
中有一个空的 []
数组,最后一个(第三个)元素在 restaurant_branch
中有数据,这导致空点异常 ("RangeError (index): Invalid value: Valid HomePage.dart
(在文本小部件中)代码中的值范围为空:0")。那么如何防止这个问题。
json data
{
"message": "restaurants returned",
"data": [
{
"id": 40,
"name": "Arnulfo",
"aboutUs": "Voluptate omnis consequatur saepe doloribus tempore quia error. Praesentium esse blanditiis illo eos qui et deserunt rerum. Velit provident aliquam eveniet qui corporis. Culpa molestiae incidunt eaque unde id tempore. Tenetur ducimus amet hic sunt et.",
"phoneNumber": 58432,
"address": "70990 Stark Streets",
"latitude": "73.6105",
"longitude": "-95.9985",
"image": "https://cdn.fakercloud.com/avatars/matthewkay__128.jpg",
"countryCode": "VE ",
"restaurantRegisterDocument": "Est qui voluptatem.",
"isDeleted": false,
"createdAt": "2021-09-04T20:24:06.310Z",
"updatedAt": "2021-09-04T20:24:06.310Z",
"restaurantTypeId": 1,
"categoryId": 1,
"userId": 3,
"user": {
"id": 3,
"firstName": "Marisa",
"lastName": "Mills",
"email": "Darrick_Reichert94@gmail.com",
"phoneNumber": "90428",
"address": "870 Guadalupe River",
"gender": "female",
"language": "ar",
"createdAt": "2021-09-04T20:14:05.939Z",
"updatedAt": "2021-09-04T20:14:05.939Z"
},
"restaurant_branch": []
},
{
"id": 39,
"name": "Maynard",
"aboutUs": "Sunt veniam numquam perferendis consequatur. Accusantium mollitia nemo odit nihil alias dolor. Voluptatibus officia consectetur nihil. Voluptas eligendi aliquam.",
"phoneNumber": 93756,
"address": "38743 Freda Green",
"latitude": "-50.3143",
"longitude": "114.4596",
"image": "https://cdn.fakercloud.com/avatars/omnizya_128.jpg",
"countryCode": "PH ",
"restaurantRegisterDocument": "Voluptatem et expedita rerum eos eaque nihil et culpa.",
"isDeleted": false,
"createdAt": "2021-09-04T20:24:06.309Z",
"updatedAt": "2021-09-04T20:24:06.309Z",
"restaurantTypeId": 1,
"categoryId": 4,
"userId": 6,
"user": {
"id": 6,
"firstName": "Layne",
"lastName": "Turcotte",
"email": "Jayson_Rice@yahoo.com",
"phoneNumber": "98802",
"address": "659 Trudie Keys",
"gender": "male",
"language": "ar",
"createdAt": "2021-09-04T20:14:05.939Z",
"updatedAt": "2021-09-04T20:14:05.939Z"
},
"restaurant_branch": []
},
{
"id": 10,
"name": "Kaden",
"aboutUs": "Et dolore cumque et iusto vel qui iste facere. Quia sed minima. Porro eos inventore qui voluptas animi voluptates fuga commodi magnam. Voluptas eligendi sunt et fugiat repudiandae asperiores maxime sit. Impedit exercitationem laudantium error autem modi voluptas et. Vitae ut non voluptatem culpa eos quae occaecati.",
"phoneNumber": 94005,
"address": "920 Sawayn Street",
"latitude": "-69.1354",
"longitude": "-176.2695",
"image": "https://cdn.fakercloud.com/avatars/daniloc_128.jpg",
"countryCode": "PW ",
"restaurantRegisterDocument": "Fugiat ut autem et voluptates aut quisquam distinctio qui aut.",
"isDeleted": true,
"createdAt": "2021-09-04T20:14:06.352Z",
"updatedAt": "2021-09-04T20:14:06.352Z",
"restaurantTypeId": 6,
"categoryId": 3,
"userId": 4,
"user": {
"id": 4,
"firstName": "Santiago",
"lastName": "Kling",
"email": "Yoshiko.Block@yahoo.com",
"phoneNumber": "4436",
"address": "809 Earlene Square",
"gender": "female",
"language": "ar",
"createdAt": "2021-09-04T20:14:05.939Z",
"updatedAt": "2021-09-04T20:14:05.939Z"
},
"restaurant_branch": [
{
"id": 4,
"name": "Audreanne",
"description": "Kreiger",
"email": "Waylon.Osinski@yahoo.com",
"phoneNumber": 95645,
"address": "91601 Clifford Bypass",
"country_code": "SM ",
"image": "https://cdn.fakercloud.com/avatars/nicolasfolliot_128.jpg",
"latitude": "-42.0925",
"longitude": "-111.4455",
"workingHours": "Carolina AI Fresh",
"workingDays": "Friday",
"offDays": "Thursday",
"locationAddress": "802 Hoppe Ranch",
"locationCity": "Diamond Bar",
"status": 2,
"hasParking": true,
"instruction": "Bogan",
"isActive": true,
"isDeleted": false,
"createdAt": "2021-09-04T20:14:07.204Z",
"updatedAt": "2021-09-04T20:14:07.204Z",
"restaurantId": 10,
"cityId": 6,
"districtId": 1,
"feedbacks": [
{
"id": 39,
"comment": "International Communications Officer",
"star": 3,
"createdAt": "2021-09-04T20:24:07.433Z",
"updatedAt": "2021-09-04T20:24:07.433Z",
"customerId": 1,
"restaurantBranchId": 4
}
]
},
]
}
RecommendedForYouModel
class RecommendedForYouDataRestaurantBranchFeedbacks {
int? id;
String? comment;
int? star;
String? createdAt;
String? updatedAt;
int? customerId;
int? restaurantBranchId;
RecommendedForYouDataRestaurantBranchFeedbacks({
this.id,
this.comment,
this.star,
this.createdAt,
this.updatedAt,
this.customerId,
this.restaurantBranchId,
});
RecommendedForYouDataRestaurantBranchFeedbacks.fromJson(
Map<String, dynamic> json) {
id = json["id"]?.toInt();
comment = json["comment"]?.toString();
star = json["star"]?.toInt();
createdAt = json["createdAt"]?.toString();
updatedAt = json["updatedAt"]?.toString();
customerId = json["customerId"]?.toInt();
restaurantBranchId = json["restaurantBranchId"]?.toInt();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
data["comment"] = comment;
data["star"] = star;
data["createdAt"] = createdAt;
data["updatedAt"] = updatedAt;
data["customerId"] = customerId;
data["restaurantBranchId"] = restaurantBranchId;
return data;
}
}
class RecommendedForYouDataRestaurantBranch {
int? id;
String? name;
String? description;
String? email;
int? phoneNumber;
String? address;
String? countryCode;
String? image;
String? latitude;
String? longitude;
String? workingHours;
String? workingDays;
String? offDays;
String? locationAddress;
String? locationCity;
int? status;
bool? hasParking;
String? instruction;
bool? isActive;
bool? isDeleted;
String? createdAt;
String? updatedAt;
int? restaurantId;
int? cityId;
int? districtId;
List<RecommendedForYouDataRestaurantBranchFeedbacks?>? feedbacks;
RecommendedForYouDataRestaurantBranch({
this.id,
this.name,
this.description,
this.email,
this.phoneNumber,
this.address,
this.countryCode,
this.image,
this.latitude,
this.longitude,
this.workingHours,
this.workingDays,
this.offDays,
this.locationAddress,
this.locationCity,
this.status,
this.hasParking,
this.instruction,
this.isActive,
this.isDeleted,
this.createdAt,
this.updatedAt,
this.restaurantId,
this.cityId,
this.districtId,
this.feedbacks,
});
RecommendedForYouDataRestaurantBranch.fromJson(Map<String, dynamic> json) {
id = json["id"]?.toInt();
name = json["name"]?.toString();
description = json["description"]?.toString();
email = json["email"]?.toString();
phoneNumber = json["phoneNumber"]?.toInt();
address = json["address"]?.toString();
countryCode = json["country_code"]?.toString();
image = json["image"]?.toString();
latitude = json["latitude"]?.toString();
longitude = json["longitude"]?.toString();
workingHours = json["workingHours"]?.toString();
workingDays = json["workingDays"]?.toString();
offDays = json["offDays"]?.toString();
locationAddress = json["locationAddress"]?.toString();
locationCity = json["locationCity"]?.toString();
status = json["status"]?.toInt();
hasParking = json["hasParking"];
instruction = json["instruction"]?.toString();
isActive = json["isActive"];
isDeleted = json["isDeleted"];
createdAt = json["createdAt"]?.toString();
updatedAt = json["updatedAt"]?.toString();
restaurantId = json["restaurantId"]?.toInt();
cityId = json["cityId"]?.toInt();
districtId = json["districtId"]?.toInt();
if (json["feedbacks"] != null) {
final v = json["feedbacks"];
final arr0 = <RecommendedForYouDataRestaurantBranchFeedbacks>[];
v.forEach((v) {
arr0.add(RecommendedForYouDataRestaurantBranchFeedbacks.fromJson(v));
});
feedbacks = arr0;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
data["name"] = name;
data["description"] = description;
data["email"] = email;
data["phoneNumber"] = phoneNumber;
data["address"] = address;
data["country_code"] = countryCode;
data["image"] = image;
data["latitude"] = latitude;
data["longitude"] = longitude;
data["workingHours"] = workingHours;
data["workingDays"] = workingDays;
data["offDays"] = offDays;
data["locationAddress"] = locationAddress;
data["locationCity"] = locationCity;
data["status"] = status;
data["hasParking"] = hasParking;
data["instruction"] = instruction;
data["isActive"] = isActive;
data["isDeleted"] = isDeleted;
data["createdAt"] = createdAt;
data["updatedAt"] = updatedAt;
data["restaurantId"] = restaurantId;
data["cityId"] = cityId;
data["districtId"] = districtId;
if (feedbacks != null) {
final v = feedbacks;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data["feedbacks"] = arr0;
}
return data;
}
}
class RecommendedForYouDataUser {
int? id;
String? firstName;
String? lastName;
String? email;
String? phoneNumber;
String? address;
String? gender;
String? language;
String? createdAt;
String? updatedAt;
RecommendedForYouDataUser({
this.id,
this.firstName,
this.lastName,
this.email,
this.phoneNumber,
this.address,
this.gender,
this.language,
this.createdAt,
this.updatedAt,
});
RecommendedForYouDataUser.fromJson(Map<String, dynamic> json) {
id = json["id"]?.toInt();
firstName = json["firstName"]?.toString();
lastName = json["lastName"]?.toString();
email = json["email"]?.toString();
phoneNumber = json["phoneNumber"]?.toString();
address = json["address"]?.toString();
gender = json["gender"]?.toString();
language = json["language"]?.toString();
createdAt = json["createdAt"]?.toString();
updatedAt = json["updatedAt"]?.toString();
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
data["firstName"] = firstName;
data["lastName"] = lastName;
data["email"] = email;
data["phoneNumber"] = phoneNumber;
data["address"] = address;
data["gender"] = gender;
data["language"] = language;
data["createdAt"] = createdAt;
data["updatedAt"] = updatedAt;
return data;
}
}
class RecommendedForYouData {
int? id;
String? name;
String? aboutUs;
int? phoneNumber;
String? address;
String? latitude;
String? longitude;
String? image;
String? countryCode;
String? restaurantRegisterDocument;
bool? isDeleted;
String? createdAt;
String? updatedAt;
int? restaurantTypeId;
int? categoryId;
int? userId;
RecommendedForYouDataUser? user;
List<RecommendedForYouDataRestaurantBranch?>? restaurantBranch;
RecommendedForYouData({
this.id,
this.name,
this.aboutUs,
this.phoneNumber,
this.address,
this.latitude,
this.longitude,
this.image,
this.countryCode,
this.restaurantRegisterDocument,
this.isDeleted,
this.createdAt,
this.updatedAt,
this.restaurantTypeId,
this.categoryId,
this.userId,
this.user,
this.restaurantBranch,
});
RecommendedForYouData.fromJson(Map<String, dynamic> json) {
id = json["id"]?.toInt();
name = json["name"]?.toString();
aboutUs = json["aboutUs"]?.toString();
phoneNumber = json["phoneNumber"]?.toInt();
address = json["address"]?.toString();
latitude = json["latitude"]?.toString();
longitude = json["longitude"]?.toString();
image = json["image"]?.toString();
countryCode = json["countryCode"]?.toString();
restaurantRegisterDocument = json["restaurantRegisterDocument"]?.toString();
isDeleted = json["isDeleted"];
createdAt = json["createdAt"]?.toString();
updatedAt = json["updatedAt"]?.toString();
restaurantTypeId = json["restaurantTypeId"]?.toInt();
categoryId = json["categoryId"]?.toInt();
userId = json["userId"]?.toInt();
user = (json["user"] != null)
? RecommendedForYouDataUser.fromJson(json["user"])
: null;
if (json["restaurant_branch"] != null) {
final v = json["restaurant_branch"];
final arr0 = <RecommendedForYouDataRestaurantBranch>[];
v.forEach((v) {
arr0.add(RecommendedForYouDataRestaurantBranch.fromJson(v));
});
restaurantBranch = arr0;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["id"] = id;
data["name"] = name;
data["aboutUs"] = aboutUs;
data["phoneNumber"] = phoneNumber;
data["address"] = address;
data["latitude"] = latitude;
data["longitude"] = longitude;
data["image"] = image;
data["countryCode"] = countryCode;
data["restaurantRegisterDocument"] = restaurantRegisterDocument;
data["isDeleted"] = isDeleted;
data["createdAt"] = createdAt;
data["updatedAt"] = updatedAt;
data["restaurantTypeId"] = restaurantTypeId;
data["categoryId"] = categoryId;
data["userId"] = userId;
if (user != null) {
data["user"] = user!.toJson();
}
if (restaurantBranch != null) {
final v = restaurantBranch;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data["restaurant_branch"] = arr0;
}
return data;
}
}
class RecommendedForYou {
String? message;
List<RecommendedForYouData?>? data;
RecommendedForYou({
this.message,
this.data,
});
RecommendedForYou.fromJson(Map<String, dynamic> json) {
message = json["message"]?.toString();
if (json["data"] != null) {
final v = json["data"];
final arr0 = <RecommendedForYouData>[];
v.forEach((v) {
arr0.add(RecommendedForYouData.fromJson(v));
});
this.data = arr0;
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = Map<String, dynamic>();
data["message"] = message;
if (this.data != null) {
final v = this.data;
final arr0 = [];
v!.forEach((v) {
arr0.add(v!.toJson());
});
data["data"] = arr0;
}
return data;
}
}
HomePage.dart
Container(
child: Padding(
padding:
const EdgeInsets.only(top: 20.0, left: 20.0, right: 20.0),
child: Container(
height: height,
child: BlocBuilder<RecommendedBloc, RecommendedState>(
builder: (context, state) {
if (state is LoadingRecommendedState) {
return Center(
child: PlatformCircularProgressIndicator());
} else if (state is LoadedRecommendedForYouState) {
return buildRecommendationRestaurant(state.data);
} else if (state is ErrorRecommendedState) {
return Center(child: Text(state.message));
}
return Container();
}),
),
),
),
Widget buildRecommendationRestaurant(List<RecommendedForYouData> data) {
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: data.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
child: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Card(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Padding(
padding: const EdgeInsets.only(top: 5.0, right: 5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Icon(
Icons.near_me,
size: 10.0,
),
Padding(
padding: const EdgeInsets.only(left: 5.0),
child: Text(
'5km',
style: TextStyle(fontSize: 10.0),
),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(left: 5.0),
child: CachedNetworkImage(
imageUrl: data[index].image!,
fit: BoxFit.cover,
placeholder: (context, url) => Center(
child:
PlatformCircularProgressIndicator()),
errorWidget: (context, url, error) =>
Icon(Icons.error),
height:
MediaQuery.of(context).size.width * 0.18,
width:
MediaQuery.of(context).size.width * 0.18,
),
),
Padding(
padding: const EdgeInsets.only(
left: 10.0, right: 35.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
data[index].name!,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20.0),
),
Row(
children: [
Text(
'4.5',
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500),
),
Text(
'(${data[index].restaurantBranch![index]!.feedbacks!.length.toString()} RATING)', //Here on this line getting null because first element is []
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500),
)
],
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Row(
children: [
ImageIcon(
AssetImage(
'images/food-serving.png'),
size: 15.0,
),
Text(
'Italian Food - Steake',
style: TextStyle(fontSize: 12.0),
)
],
),
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Row(
children: [
Icon(
Icons.location_on_outlined,
size: 12.0,
color: TuxedoColor.greyColor,
),
Text(
'Riyadh',
style: TextStyle(
fontSize: 12.0,
fontWeight: FontWeight.w600),
)
],
),
)
],
),
),
],
),
),
],
),
)),
),
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => DetailsPage(
id: data[index].id!,
)));
},
);
});
}
您还在为 restaurant_branch
数组使用父 listView 的 index
变量。由于 restaurant_branch
是一个不同的数组,如果您想在布局上有效地显示分支,您应该使用嵌套的 ListView。在你的情况下,如果每个 restaurant
没有多个分支,你可以像这样使用它
.......
Row(
children: [
Text(
'4.5',
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500),
),
Text(
'(${data[index].restaurantBranch![0]!.feedbacks!.length.toString()} RATING)', //Here on this line getting null because first element is []
style: TextStyle(
fontSize: 10.0,
fontWeight: FontWeight.w500),
)
],
),
......