如何修复错误代码 "type 'null' is not a subtype of type 'map string dynamic '"
How to fix error code "type 'null' is not a subtype of type 'map string dynamic '"
我正在尝试为学校项目打印 API 地震数据,但出现错误:
type 'null' is not a subtype of type 'map string dynamic '.
如何解决这个问题? API 正常工作。这是我的代码:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Album> createAlbum(String events) async {
final response = await http.get(Uri.parse('https://cdn.knmi.nl/knmi/map/page/seismologie/all_induced.json')); // url api
if (response.statusCode == 200) {
// status code moet 200 zijn om uit te printen.
print(response.body); // in de console word alle data geprint
final json = jsonDecode(response.body);
return Album.fromJson(json[0]);
} else {
throw Exception(response.statusCode.toString()); // status code word geprint als het niet gelijk is aan 200
}
}
class Album {
final String events;
Album({required this.events});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
events: json['events'] as String, // variable fact word gepakt om uit te printen
// place: json['[place]'],
// generated: json['generated'],
// coordinates: json['coordinates'],
);
}
}
void main() {
runApp(const MaterialApp(
title: 'Test', // class om een titel aan te maken in de appbar
home: FirstRoute(),
));
}
class FirstRoute extends StatefulWidget {
const FirstRoute({Key? key}) : super(key: key);
@override
_MyAppState createState() {
return _MyAppState();
}
}
class _MyAppState extends State<FirstRoute> {
final TextEditingController _controller = TextEditingController();
Future <Album>? _futureAlbum;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Honden Feiten',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Honden Feiten'),
),
body: Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(9.0),
child: (_futureAlbum== null ) ? buildColumn() : buildFutureBuilder(),
),
),
);
}
Column buildColumn() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.network('https://e7.pngegg.com/pngimages/496/352/png-clipart-osaka-earthquake-computer-icons-earthquake-engineering-earthquakes-text-logo-thumbnail.png'),
ElevatedButton( // knop met de future album word geprint
onPressed: () {
setState(() {
_futureAlbum = createAlbum(_controller.text); // de class wordt geprint waar de variable van de API in staan.
});
},
child: const Text('Klik hier voor een honden feitje! (in het engels)'),
),
],
);
}
// error code of niet
FutureBuilder<Album> buildFutureBuilder() {
return FutureBuilder<Album>(
future: _futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.events );
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
);
}
}
https://github.com/Lavkushwaha/Whosebug_Student
首先你不需要索引在json[0]
它不是列表所以你可以直接使用
: 行号 14
return Album.fromJson(json[0]);
然后你会报错:行号 31
_CastError (type 'List<dynamic>' is not a subtype of type 'String' in type cast)
因为事件是列表而不是字符串,而您正在尝试将其映射为字符串。
我告诉你简单的解决方法
从 API 复制 json 响应,转到 QuickType -> select dart,创建
它的飞镖模型
在成功响应中直接用你的json响应投模型;
然后您可以在您的应用程序中访问它
如果您还需要什么,请告诉我。
谢谢
为您的项目添加了工作代码
https://github.com/Lavkushwaha/Whosebug_Student
只需创建一个文件earthquake.model.dart粘贴它
现在在第 14 行更改 final earthquake = earthquakeFromJson(jsonString);
// To parse this JSON data, do
//
// final earthquake = earthquakeFromJson(jsonString);
import 'dart:convert';
Earthquake earthquakeFromJson(String str) => Earthquake.fromJson(json.decode(str));
String earthquakeToJson(Earthquake data) => json.encode(data.toJson());
class Earthquake {
Earthquake({
this.events,
});
final List<Event> events;
factory Earthquake.fromJson(Map<String, dynamic> json) => Earthquake(
events: json["events"] == null ? null : List<Event>.from(json["events"].map((x) => Event.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"events": events == null ? null : List<dynamic>.from(events.map((x) => x.toJson())),
};
}
class Event {
Event({
this.date,
this.depth,
this.evaluationMode,
this.lat,
this.lon,
this.mag,
this.place,
this.time,
this.type,
});
final DateTime date;
final String depth;
final EvaluationMode evaluationMode;
final String lat;
final String lon;
final String mag;
final String place;
final String time;
final Type type;
factory Event.fromJson(Map<String, dynamic> json) => Event(
date: json["date"] == null ? null : DateTime.parse(json["date"]),
depth: json["depth"] == null ? null : json["depth"],
evaluationMode: json["evaluationMode"] == null ? null : evaluationModeValues.map[json["evaluationMode"]],
lat: json["lat"] == null ? null : json["lat"],
lon: json["lon"] == null ? null : json["lon"],
mag: json["mag"] == null ? null : json["mag"],
place: json["place"] == null ? null : json["place"],
time: json["time"] == null ? null : json["time"],
type: json["type"] == null ? null : typeValues.map[json["type"]],
);
Map<String, dynamic> toJson() => {
"date": date == null ? null : "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
"depth": depth == null ? null : depth,
"evaluationMode": evaluationMode == null ? null : evaluationModeValues.reverse[evaluationMode],
"lat": lat == null ? null : lat,
"lon": lon == null ? null : lon,
"mag": mag == null ? null : mag,
"place": place == null ? null : place,
"time": time == null ? null : time,
"type": type == null ? null : typeValues.reverse[type],
};
}
enum EvaluationMode { MANUAL }
final evaluationModeValues = EnumValues({
"manual": EvaluationMode.MANUAL
});
enum Type { INDUCED_EARTHQUAKE }
final typeValues = EnumValues({
"induced earthquake": Type.INDUCED_EARTHQUAKE
});
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;
}
}
我正在尝试为学校项目打印 API 地震数据,但出现错误:
type 'null' is not a subtype of type 'map string dynamic '.
如何解决这个问题? API 正常工作。这是我的代码:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Album> createAlbum(String events) async {
final response = await http.get(Uri.parse('https://cdn.knmi.nl/knmi/map/page/seismologie/all_induced.json')); // url api
if (response.statusCode == 200) {
// status code moet 200 zijn om uit te printen.
print(response.body); // in de console word alle data geprint
final json = jsonDecode(response.body);
return Album.fromJson(json[0]);
} else {
throw Exception(response.statusCode.toString()); // status code word geprint als het niet gelijk is aan 200
}
}
class Album {
final String events;
Album({required this.events});
factory Album.fromJson(Map<String, dynamic> json) {
return Album(
events: json['events'] as String, // variable fact word gepakt om uit te printen
// place: json['[place]'],
// generated: json['generated'],
// coordinates: json['coordinates'],
);
}
}
void main() {
runApp(const MaterialApp(
title: 'Test', // class om een titel aan te maken in de appbar
home: FirstRoute(),
));
}
class FirstRoute extends StatefulWidget {
const FirstRoute({Key? key}) : super(key: key);
@override
_MyAppState createState() {
return _MyAppState();
}
}
class _MyAppState extends State<FirstRoute> {
final TextEditingController _controller = TextEditingController();
Future <Album>? _futureAlbum;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Honden Feiten',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(
title: const Text('Honden Feiten'),
),
body: Container(
alignment: Alignment.center,
padding: const EdgeInsets.all(9.0),
child: (_futureAlbum== null ) ? buildColumn() : buildFutureBuilder(),
),
),
);
}
Column buildColumn() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Image.network('https://e7.pngegg.com/pngimages/496/352/png-clipart-osaka-earthquake-computer-icons-earthquake-engineering-earthquakes-text-logo-thumbnail.png'),
ElevatedButton( // knop met de future album word geprint
onPressed: () {
setState(() {
_futureAlbum = createAlbum(_controller.text); // de class wordt geprint waar de variable van de API in staan.
});
},
child: const Text('Klik hier voor een honden feitje! (in het engels)'),
),
],
);
}
// error code of niet
FutureBuilder<Album> buildFutureBuilder() {
return FutureBuilder<Album>(
future: _futureAlbum,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data!.events );
} else if (snapshot.hasError) {
return Text('${snapshot.error}');
}
return const CircularProgressIndicator();
},
);
}
}
https://github.com/Lavkushwaha/Whosebug_Student
首先你不需要索引在json[0]
它不是列表所以你可以直接使用
: 行号 14
return Album.fromJson(json[0]);
然后你会报错:行号 31
_CastError (type 'List<dynamic>' is not a subtype of type 'String' in type cast)
因为事件是列表而不是字符串,而您正在尝试将其映射为字符串。
我告诉你简单的解决方法
从 API 复制 json 响应,转到 QuickType -> select dart,创建 它的飞镖模型
在成功响应中直接用你的json响应投模型;
然后您可以在您的应用程序中访问它
如果您还需要什么,请告诉我。
谢谢
为您的项目添加了工作代码
https://github.com/Lavkushwaha/Whosebug_Student
只需创建一个文件earthquake.model.dart粘贴它
现在在第 14 行更改 final earthquake = earthquakeFromJson(jsonString);
// To parse this JSON data, do
//
// final earthquake = earthquakeFromJson(jsonString);
import 'dart:convert';
Earthquake earthquakeFromJson(String str) => Earthquake.fromJson(json.decode(str));
String earthquakeToJson(Earthquake data) => json.encode(data.toJson());
class Earthquake {
Earthquake({
this.events,
});
final List<Event> events;
factory Earthquake.fromJson(Map<String, dynamic> json) => Earthquake(
events: json["events"] == null ? null : List<Event>.from(json["events"].map((x) => Event.fromJson(x))),
);
Map<String, dynamic> toJson() => {
"events": events == null ? null : List<dynamic>.from(events.map((x) => x.toJson())),
};
}
class Event {
Event({
this.date,
this.depth,
this.evaluationMode,
this.lat,
this.lon,
this.mag,
this.place,
this.time,
this.type,
});
final DateTime date;
final String depth;
final EvaluationMode evaluationMode;
final String lat;
final String lon;
final String mag;
final String place;
final String time;
final Type type;
factory Event.fromJson(Map<String, dynamic> json) => Event(
date: json["date"] == null ? null : DateTime.parse(json["date"]),
depth: json["depth"] == null ? null : json["depth"],
evaluationMode: json["evaluationMode"] == null ? null : evaluationModeValues.map[json["evaluationMode"]],
lat: json["lat"] == null ? null : json["lat"],
lon: json["lon"] == null ? null : json["lon"],
mag: json["mag"] == null ? null : json["mag"],
place: json["place"] == null ? null : json["place"],
time: json["time"] == null ? null : json["time"],
type: json["type"] == null ? null : typeValues.map[json["type"]],
);
Map<String, dynamic> toJson() => {
"date": date == null ? null : "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}",
"depth": depth == null ? null : depth,
"evaluationMode": evaluationMode == null ? null : evaluationModeValues.reverse[evaluationMode],
"lat": lat == null ? null : lat,
"lon": lon == null ? null : lon,
"mag": mag == null ? null : mag,
"place": place == null ? null : place,
"time": time == null ? null : time,
"type": type == null ? null : typeValues.reverse[type],
};
}
enum EvaluationMode { MANUAL }
final evaluationModeValues = EnumValues({
"manual": EvaluationMode.MANUAL
});
enum Type { INDUCED_EARTHQUAKE }
final typeValues = EnumValues({
"induced earthquake": Type.INDUCED_EARTHQUAKE
});
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;
}
}