类型列表<dynamic>不是 Map<String Dynamic 类型的子类型>



我对Flutter编程很陌生,我正在尝试导入包含图书数据的本地JSON文件,如标题,作者,发行年份等。

最初,我使用JSON到DART转换器来组装一个图书数据模型,我现在试图使getBooksAll()函数,其中程序获得本地JSON文件,并使用BookData类的fromJson()方法将数据解析为Map。

我得到的问题是json.decode(value)返回类型List<dynamic>,fromJson()方法接受类型Map<String, dynamic>我该如何解决这个问题?

getBooksAll()代码:

static getBooksAll() {
var booksJson = rootBundle.loadString('assets/bookData.json');
booksJson.then((value) => BookData.fromJson(json.decode(value)));
}

下面是我得到的错误:

E/flutter (10608): [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>'
E/flutter (10608): #0      BookData.getBooksAll.<anonymous closure> (package:well_red_v1/models/book_data_model.dart:56:54)
E/flutter (10608): #1      _rootRunUnary (dart:async/zone.dart:1436:47)
E/flutter (10608): #2      _CustomZone.runUnary (dart:async/zone.dart:1335:19)
E/flutter (10608): <asynchronous suspension>
E/flutter (10608): 

下面是整本书的数据模型代码:

import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:flutter/services.dart' show rootBundle;
class BookData {
Id? id;
String? title;
String? isbn;
int? pageCount;
PublishedDate? publishedDate;
String? thumbnailUrl;
String? shortDescription;
String? longDescription;
String? status;
List<dynamic>? authors;
List<dynamic>? categories;
BookData({this.id, this.title, this.isbn, this.pageCount, this.publishedDate, this.thumbnailUrl, this.shortDescription, this.longDescription, this.status, this.authors, this.categories});
BookData.fromJson(Map<String, dynamic> json) {
this.id = json["_id"] == null ? null : Id.fromJson(json["_id"]);
this.title = json["title"];
this.isbn = json["isbn"];
this.pageCount = json["pageCount"];
this.publishedDate = json["publishedDate"] == null ? null : PublishedDate.fromJson(json["publishedDate"]);
this.thumbnailUrl = json["thumbnailUrl"];
this.shortDescription = json["shortDescription"];
this.longDescription = json["longDescription"];
this.status = json["status"];
this.authors = json["authors"] ?? [];
this.categories = json["categories"] ?? [];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if(this.id != null)
data["_id"] = this.id?.toJson();
data["title"] = this.title;
data["isbn"] = this.isbn;
data["pageCount"] = this.pageCount;
if(this.publishedDate != null)
data["publishedDate"] = this.publishedDate?.toJson();
data["thumbnailUrl"] = this.thumbnailUrl;
data["shortDescription"] = this.shortDescription;
data["longDescription"] = this.longDescription;
data["status"] = this.status;
if(this.authors != null)
data["authors"] = this.authors;
if(this.categories != null)
data["categories"] = this.categories;
return data;
}
static getBooksAll() {
var booksJson = rootBundle.loadString('assets/bookData.json');
booksJson.then((value) => BookData.fromJson(json.decode(value)));
}
}
class PublishedDate {
String? $date;
PublishedDate({this.$date});
PublishedDate.fromJson(Map<String, dynamic> json) {
this.$date = json["${$date}"];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data["${$date}"] = this.$date;
return data;
}
}
class Id {
String? $oid;
Id({this.$oid});
Id.fromJson(Map<String, dynamic> json) {
this.$oid = json["${$oid}"];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data["${$oid}"] = this.$oid;
return data;
}
}

这是JSON文件的一部分:

[
{
"_id": 1,
"title": "Unlocking Android",
"isbn": "1933988673",
"pageCount": 416,
"publishedDate": {
"$date": "2009-04-01T00:00:00.000-0700"
},
"thumbnailUrl": "https://s3.amazonaws.com/AKIAJC5RLADLUMVRPFDQ.book-thumb-images/ableson.jpg",
"shortDescription": "Unlocking Android: A Developer's Guide provides concise, hands-on instruction for the Android operating system and development tools. This book teaches important architectural concepts in a straightforward writing style and builds on this with practical and useful examples throughout.",
"longDescription": "Android is an open source mobile phone platform based on the Linux operating system and developed by the Open Handset Alliance, a consortium of over 30 hardware, software and telecom companies that focus on open standards for mobile devices. Led by search giant, Google, Android is designed to deliver a better and more open and cost effective mobile experience.    Unlocking Android: A Developer's Guide provides concise, hands-on instruction for the Android operating system and development tools. This book teaches important architectural concepts in a straightforward writing style and builds on this with practical and useful examples throughout. Based on his mobile development experience and his deep knowledge of the arcane Android technical documentation, the author conveys the know-how you need to develop practical applications that build upon or replace any of Androids features, however small.    Unlocking Android: A Developer's Guide prepares the reader to embrace the platform in easy-to-understand language and builds on this foundation with re-usable Java code examples. It is ideal for corporate and hobbyists alike who have an interest, or a mandate, to deliver software functionality for cell phones.    WHAT'S INSIDE:        * Android's place in the market      * Using the Eclipse environment for Android development      * The Intents - how and why they are used      * Application classes:            o Activity            o Service            o IntentReceiver       * User interface design      * Using the ContentProvider to manage data      * Persisting data with the SQLite database      * Networking examples      * Telephony applications      * Notification methods      * OpenGL, animation & multimedia      * Sample Applications  ",
"status": "PUBLISH",
"authors": [
"W. Frank Ableson",
"Charlie Collins",
"Robi Sen"
],
"categories": [
"Open Source",
"Mobile"
]
},
{
"_id": 2,
"title": "Android in Action, Second Edition",
"isbn": "1935182722",
"pageCount": 592,
"publishedDate": {
"$date": "2011-01-14T00:00:00.000-0800"
},
"thumbnailUrl": "https://s3.amazonaws.com/AKIAJC5RLADLUMVRPFDQ.book-thumb-images/ableson2.jpg",
"shortDescription": "Android in Action, Second Edition is a comprehensive tutorial for Android developers. Taking you far beyond "Hello Android," this fast-paced book puts you in the driver's seat as you learn important architectural concepts and implementation strategies. You'll master the SDK, build WebKit apps using HTML 5, and even learn to extend or replace Android's built-in features by building useful and intriguing examples. ",
"longDescription": "When it comes to mobile apps, Android can do almost anything   and with this book, so can you! Android runs on mobile devices ranging from smart phones to tablets to countless special-purpose gadgets. It's the broadest mobile platform available.    Android in Action, Second Edition is a comprehensive tutorial for Android developers. Taking you far beyond "Hello Android," this fast-paced book puts you in the driver's seat as you learn important architectural concepts and implementation strategies. You'll master the SDK, build WebKit apps using HTML 5, and even learn to extend or replace Android's built-in features by building useful and intriguing examples. ",
"status": "PUBLISH",
"authors": [
"W. Frank Ableson",
"Robi Sen"
],
"categories": [
"Java"
]
},
{
"_id": 3,
"title": "Specification by Example",
"isbn": "1617290084",
"pageCount": 0,
"publishedDate": {
"$date": "2011-06-03T00:00:00.000-0700"
},
"thumbnailUrl": "https://s3.amazonaws.com/AKIAJC5RLADLUMVRPFDQ.book-thumb-images/adzic.jpg",
"status": "PUBLISH",
"authors": [
"Gojko Adzic"
],
"categories": [
"Software Engineering"
]
}
]

对象映射列表的解决方案:

static getBooksAll() async {
var bookURL =
"https://raw.githubusercontent.com/dineshnagarajandev/samplejson/main/books.json";
var response = await http.get(Uri.parse(bookURL));
var listToPass = jsonDecode(response.body);
List<BookData> bookData =
List<BookData>.from(listToPass.map((i) => BookData.fromJson(i)));
print(bookData);
}

注意:Id类有类型大小写问题,需要更新。您正在使用的id是int,但声明为String

查看解决方案注释

this.id = json["_id"] == null ? null : Id.fromJson(json["_id"]);

编辑:

您正在使用的模型没有将_id作为对象。您可以删除ID类并使用以下内容更新您的模型

class BookData {
int? id;
String? title;
String? isbn;
int? pageCount;
PublishedDate? publishedDate;
String? thumbnailUrl;
String? shortDescription;
String? longDescription;
String? status;
List<dynamic>? authors;
List<dynamic>? categories;
BookData(
{this.id,
this.title,
this.isbn,
this.pageCount,
this.publishedDate,
this.thumbnailUrl,
this.shortDescription,
this.longDescription,
this.status,
this.authors,
this.categories});
BookData.fromJson(Map<String, dynamic> json) {
this.id = json["_id"] == null ? null : json["_id"];
this.title = json["title"];
this.isbn = json["isbn"];
this.pageCount = json["pageCount"];
this.publishedDate = json["publishedDate"] == null
? null
: PublishedDate.fromJson(json["publishedDate"]);
this.thumbnailUrl = json["thumbnailUrl"];
this.shortDescription = json["shortDescription"];
this.longDescription = json["longDescription"];
this.status = json["status"];
this.authors = json["authors"] ?? [];
this.categories = json["categories"] ?? [];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
if (this.id != null) data["_id"] = this.id;
data["title"] = this.title;
data["isbn"] = this.isbn;
data["pageCount"] = this.pageCount;
if (this.publishedDate != null)
data["publishedDate"] = this.publishedDate?.toJson();
data["thumbnailUrl"] = this.thumbnailUrl;
data["shortDescription"] = this.shortDescription;
data["longDescription"] = this.longDescription;
data["status"] = this.status;
if (this.authors != null) data["authors"] = this.authors;
if (this.categories != null) data["categories"] = this.categories;
return data;
}
}
class PublishedDate {
String? $date;
PublishedDate({this.$date});
PublishedDate.fromJson(Map<String, dynamic> json) {
this.$date = json["${$date}"];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data["${$date}"] = this.$date;
return data;
}
}

相关内容

最新更新