【问题标题】:Eroor : Type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>' in type cast错误:类型“_InternalLinkedHashMap<String, dynamic>”不是类型转换中“List<dynamic>”类型的子类型
【发布时间】:2019-09-19 15:54:34
【问题描述】:

我是 Flutter 的新手,我尝试在“10.0.2.2:8000/api/membres”上从我的 api 获取数据,但出现错误,例如类型 List dynamic is not a subtype of type 'List. 我按照flutter的例子:https://flutter.dev/docs/cookbook/networking/fetch-data#complete-example

请帮助我学习有用的教程并告诉我如何修复此代码。

MyHomePage.dart

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:http/http.dart' as http;
import 'dart:convert';

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  static const url = "10.0.2.2:8000/api/membres";

  Future<List<Map<String, dynamic>>> _future;
  @override
  void initState() {
    super.initState();
    _future = fetch();
  }

  Future<List<Map<String, dynamic>>> fetch() {
    return http
        .get("http://10.0.2.2:8000/api/membres")
        .then((response) {
          return response.statusCode == 200
              ? response.body
              : throw 'Error when getting data';
        })
        .then((body) => json.decode(body)) //
        .then((list) => (list as List).cast<Map<String, dynamic>>());
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      body: RefreshIndicator(
        onRefresh: () async {
          _future = fetch();
          setState(() {});
          return _future;
          },
        child: FutureBuilder<List<Map<String, dynamic>>>(
          future: _future,
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Center(
                child: Container(
                  constraints: BoxConstraints.expand(),
                  child: SingleChildScrollView(
                    physics: AlwaysScrollableScrollPhysics(),
                    child: Text(snapshot.error.toString()),),),);}
            if (!snapshot.hasData) {
              return Center(
                child: CircularProgressIndicator(),
              );}
            return ListView.builder(
              itemCount: snapshot.data.length,
              itemBuilder: (BuildContext context, int index) {
                final item = snapshot.data[index];
                return ListTile(
                  title: Text(item['nom']),
                  subtitle: Text(item['prenom']),
                );
              },
            );
          },
        ),
      ),
    );
  }
}

我用 Postman 测试了 API,它可以工作:

这是错误:

在模拟器中:

【问题讨论】:

    标签: json rest api flutter


    【解决方案1】:

    你有几个问题...

    你应该整理一下fetch,把它改成async

    Future<Map<String, dynamic>> fetch() async {
      http.Response response = await http.get('http://10.0.2.2:8000/api/membres');
      if (response.statusCode != 200) return null;
      return json.decode(response.body);
    }
    

    如果您查看在 postman 中获得的 json,您会看到最上面的项目是一张地图 - 至少有一个键 membres。该键似乎包含其他地图的列表。从您的类型来看,您希望获得该列表。

    如果该假设是正确的,您可以按如下方式进行调整:

    Future<List<Map<String, dynamic>>> fetch() async {
      http.Response response = await http.get('http://10.0.2.2:8000/api/membres');
      if (response.statusCode != 200) return null;
      return List<Map<String, dynamic>>.from(json.decode(response.body)['membre']);
    }
    

    【讨论】:

    • 天啊,终于可以了,谢谢你alooooot,但是你能解释一下上面的这部分代码吗?请问是什么问题?
    • 基本上,JSON 中的任何内容都是映射(json 规范中的对象)、列表(json 规范中的数组)或值。当您调用 json.decode 时,您会返回可能是 ListMap 的内容,具体取决于 json 的内容。当您浏览/向下解码的地图/列表时,您会发现更多这样的动态事物,可能是其中之一。您的 json 肯定在顶部有一个地图,其中有一个列表作为其值。您可以通过键 ['keyName'] 索引来获得它的值,但这会给您一个 List&lt;dynamic&gt;,您可以使用 List&lt;T&gt;.from 进行转换
    • 您试图将来自您的 json 的顶级地图塞进一个列表,但它不是一个列表,而是一个地图。它的成员membre 是一个列表。 (没有双关语:会员/会员!)
    • 好吧,很清楚,你的意思是当有像“membre”这样的键时,我需要使用地图然后我使用列表?
    • 是的,如果您的 json 文本显示类似:{"membre":[{"id":"56"},{"id":"57"}]},就像在这种情况下所做的那样
    猜你喜欢
    • 1970-01-01
    • 2021-10-23
    • 2021-04-07
    • 1970-01-01
    • 2021-01-30
    • 2021-12-10
    • 1970-01-01
    • 2022-07-22
    • 2020-07-03
    相关资源
    最近更新 更多