【问题标题】: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 dart


【解决方案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

【讨论】:

    猜你喜欢
    • 2021-12-29
    • 2023-01-08
    • 2021-10-25
    • 2020-07-03
    • 2023-03-11
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 2021-09-12
    相关资源
    最近更新 更多