类型 List<dynamic> 不是类型 'Map<String, dynamic>' 的子类型

Posted

技术标签:

【中文标题】类型 List<dynamic> 不是类型 \'Map<String, dynamic>\' 的子类型【英文标题】:type List<dynamic> is not a subtype of type 'Map<String, dynamic>'类型 List<dynamic> 不是类型 'Map<String, dynamic>' 的子类型 【发布时间】:2019-12-05 10:08:08 【问题描述】:

我正在尝试从 API 获取数据。我收到错误“类型列表不是 Map 的子类型。我是新手,不明白我在哪里犯错。

这是我的获取帖子功能:

Future<Post> fetchPost() async 
  final response = await http.get('http://starlord.hackerearth.com/beercraft');

  if (response.statusCode == 200) 
    return Post.fromJson(json.decode(response.body));
   else 
    throw Exception('Failed to load post');
  

在我的主屏幕中,我正在使用这样的FutureBuilder

final Future<Post> post;
HomeScreen(Key key, this.post) : super(key: key);

FutureBuilder<Post>(
          future: post,
          builder: (context, result) 
            if (result.hasData) 
              return ListView.builder(
                itemBuilder: (context, index)
                  return cartItemComponent(result.data.name, result.data.abv, result.data.ounces);
                ,
              );
             else if (result.hasError) 
              return Text("$result.error");
            

            // By default, show a loading spinner.
            return CircularProgressIndicator();
          ,

如何解决此错误?提前致谢。

【问题讨论】:

Flutter _TypeError (type 'List<dynamic>' is not a subtype of type 'Map<String, dynamic>')的可能重复 【参考方案1】:

原因是您正在调用的 API (http://starlord.hackerearth.com/beercraft) 返回 JSON 对象的列表,但您处理它时好像只有一个对象。

您需要重写代码以将其作为 列表 处理,这应该与您的 ListView 完美配合:

Future<List<Post>> fetchPosts() async 
  final response = await http.get('http://starlord.hackerearth.com/beercraft');

  if (response.statusCode == 200) 
    return json.decode(response.body).map<Post>((item) => Post.fromJson(item)).toList();
   else 
    throw Exception('Failed to load post');
  

fetchPost 需要更新为 fetchPosts 以返回 Future&lt;List&lt;Post&gt;&gt;。在这里,您可以使用 List.map 将响应列表中的每个项目简单地映射到 Post 对象。 下一步是将返回的Future 作为FutureBuilder 中的列表处理,如下所示:

final Future<List<Post>> posts;

FutureBuilder(
    future: posts,
    builder: (context, AsyncSnapshot<List<Post>> snapshot) 
      if (snapshot.hasData) 
        return ListView(
          children: snapshot.data.map<Widget>((post) 
            return cartItemComponent(post.name, post.abv, post.ounces);
          ).toList(),
        );
       else if (snapshot.hasError) 
        return Text('$snapshot.error');
      

      // By default, show a loading spinner.
      return const CircularProgressIndicator();
    
)

请注意,我只是将列表作为Widget 的列表传递给ListViewchildren 参数,因为在这种情况下不需要构建器。 我只是再次使用map 方法,使用您的cartItemComponent 函数将Post 转换为Widget

【讨论】:

以上是关于类型 List<dynamic> 不是类型 'Map<String, dynamic>' 的子类型的主要内容,如果未能解决你的问题,请参考以下文章

类型 List<dynamic> 不是类型 'Map<String, dynamic>' 的子类型

_TypeError(类型 'List<dynamic>' 不是类型 'Map<String, dynamic> 的子类型

未处理的异常:类型 'List<dynamic>' 不是类型 'Map<String, dynamic>' 的子类型

我得到一个 - 类型 'List<dynamic>' 不是类型 'Map<String, dynamic>' 的子类型错误

未处理的异常:类型 'List<dynamic>' 不是类型 'Map<String, dynamic

_TypeError(类型'List<dynamic>'不是'Map<String,dynamic>'类型的子类型)