我正在尝试从项目中的API获取JSON数据。然而,我遇到了一个错误,我完全陷入了困境。在反序列化JSON对象方面,我还是个新手,所以非常感谢您在这方面的帮助。
这是我的JSON文件
{
"status": 200,
"data": [
{
"id": 1,
"title": "Down-sized 4thgeneration leverage",
"description": "Distinctio voluptas ea aliquid",
"address": "2755 Raul EstatenWest 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/"
}
}
]
}
我的家庭文件部分如下:
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,
),
),
);
}
},
))
],
) ,
),
这是我的豆类(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,
};
}
这是我的get-cars方法和JSON响应体
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());
}
我得到了这样的错误:";未处理的异常:NoSuchMethodError:对null调用了方法"map">
以下是我的调试控制台所说的:
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>
问题是您正在将respons.body[quot;data"][quot;data"]传递给您的Datum.fromJson((构造函数,但json中没有这样的键。另一方面,您将response.body["data"]传递给Car.fromJson((构造函数,该构造函数是一个没有"data"的数据列表;"状态";钥匙在里面。
请尝试按以下方式更改代码。
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));
}
和你的汽车类如下。
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())),
};
}
按如下方式更改build
方法。因为现在您没有来自snapshot
的列表,所以它是Car
对象,并且它具有data
属性,该属性具有Datum
对象的列表
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,
),
),
);
}
},
))
],
) ,
),