来自 API 请求的错误“在 null 上调用了方法 '[]'。接收方:null 尝试调用:[](0)”更新

Posted

技术标签:

【中文标题】来自 API 请求的错误“在 null 上调用了方法 \'[]\'。接收方:null 尝试调用:[](0)”更新【英文标题】:The error from API request "The method '[]' was called on null. Receiver: null Tried calling: [](0)" Update来自 API 请求的错误“在 null 上调用了方法 '[]'。接收方:null 尝试调用:[](0)”更新 【发布时间】:2021-06-08 12:20:28 【问题描述】:

我正在尝试使用来自 API 的数据,但我需要的数据是针对不同的请求而找到的。在flutter中有future.waite,我可以请求API的必要部分。这个想法是我正在尝试为火车创建时间表。在这个列车时刻表中,我需要列车号、站台名称和到达时间。我正在尝试按照文档和视频中的描述做所有事情,但我做不到,因为我收到错误 'The method '[]' was called on null. Receiver: null Tried calling: []("st_title")'

在问这里之前,我试着做这样的事情:

body:ListView.builder(itemBuilder: (context, index)
          return ListTile(
            title: Text(stops[index]['st_title']),

但它不起作用并给我一个错误:

在 null 上调用了方法“[]”。接收者:null 尝试调用:

我在这里看到了类似错误的解决方案,但我已经尝试了所有解决方案,但无法弄清楚我到底做错了什么。 你能指出我吗? 可能是我实际上并没有意识到我应该做什么的概念。 你们能帮帮我吗?

我的完整代码是:

Map <String, dynamic> stops;
  Map <String, dynamic> marhe;
 Map <String, dynamic> arrival;
 
@override
  void initState() 
    // TODO: implement initState
    super.initState();

    fetchData();
  

 Future fetchData() async
    String username = '***';
    String password = '***';
    String basicAuth =
        'Basic ' + base64Encode(utf8.encode('$username:$password'));
    print(basicAuth);
  final result = await Future.wait([
    http.get( 'http://link/getTableCur.php?fmt=json',
        headers: <String, String>'authorization': basicAuth),
    http.get( 'http://link//getStops.php?fmt=json',
        headers: <String, String>'authorization': basicAuth),
    http.get( 'http://link//getMarshes.php?fmt=json',
        headers: <String, String>'authorization': basicAuth),
  ]);
  setState(() 
    stops = json.decode(result[0].body);
    marhe = json.decode(result[1].body);
    arrival = json.decode(result[2].body);
  );
  


  @override


  Widget build(BuildContext context) 
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
        ),
        body:ListView.builder(itemBuilder: (context, index)
          return ListTile(
            title: Text(stops[index]['st_title']),
            leading: Text(marhe['mr_num']),
            subtitle: Text(arrival['ta_arrivetime'].toString()),
          );
        
            //title: Text(arrival[index]['tc_arrivetime']?? ''),
          ),

更新!

感谢@Patrick Freitas 帮助我,我试图按照他说的做,但现在我得到了一个错误:

The getter 'length' was called on null.
Receiver: null
Tried calling: length

以下代码:

 body:  stops.length > 0 ? ListView.builder(
              //itemCount: stops.length,
              itemBuilder: (BuildContext context, int index) 
                return ListTile(
                 trailing: Text(marhe[index]["mr_num"]),
                  title: Text(stops[index]['st_title']),
                 // subtitle: Text(arrival[index]["ta_arrivetime"]),
                );
              ,
            ) : CircularProgressIndicator()
        )

当我使用isDataObtained ? ListView.builder...:CircularProgressIndicator()时也是如此

然后它给了我无尽的加载,屏幕上没有数据出现。它还给出了一个错误"Error: List&lt;dynamic&gt; is not a subtype of type Map&lt;String, dynamic&gt;" 我也找到了关于这个问题的类似问题解决方案 - Error: List<dynamic> is not a subtype of type Map<String, dynamic>

我的代码如下所示:

 setState(() 

      stops = json.decode(result[0].body[0]);
      marhe = json.decode(result[1].body[0]);
      arrival = json.decode(result[2].body[0]);
      isDataObtained = true;
    );
  

我的所有这些链接的 json 看起来像这样:

for **getTableAll**
[
  
    "ta_id": 1,
    "srv_id": 1,
    "st_id": 3026,
    "mr_id": 305,
    "rl_racetype": "B",
    "uniqueid": 21,
    "ta_systime": "2021-03-11 15:01:47",
    "ta_arrivetime": "2021-03-11 15:06:11",
    "mv_id": 957,
    "rc_kkp": "",
    "ta_len2target": 4.996839,
    "u_inv": false
  ,
  
for **getStops**

    "st_id": 1,
    "ok_id": "18410",
    "sr_id": 0,
    "st_title": "Station1",
    "st_desc": "Station1",
  ,

for **Marshes:** 
[
  
    "mr_id": 1,
    "tt_id": 1,
    "mt_id": 2,
    "mr_num": "112",
  
  ,

这是三个数组,我需要同时来自所有三个数组的数据:如上所述,我需要到达时间、列车号和站台名称的数据。我尝试使用颤振文档中描述的经典数据检索,但对我没有任何帮助。在 *** 上,有人告诉我我需要使用 Future.wait,但现在我卡住并感到困惑。

【问题讨论】:

【参考方案1】:

Flutter 不知道您的异步请求是否已经返回,因此它试图在没有任何信息的情况下呈现一个数组。为防止这种情况,您可以添加一个 IF 验证来验证您的数组是否已被填充。

使用三元 if:

body:
   stops.length > 0 ? ​
      ListView.builder(...) :
      CircularProgressIndicator() 

由于您要填充三个数组,因此您可以创建一个布尔值来控制您的请求是否已经填充了所有三个数组,例如 isDataObtained

Map <String, dynamic> stops;
Map <String, dynamic> marhe;
Map <String, dynamic> arrival;
bool isDataObtained = false;


Widget build(BuildContext context) 
    return MaterialApp(
        home: Scaffold(
            appBar: AppBar(),
            body:
                isDataObtained ? ​
                    ListView.builder(...) :
                    CircularProgressIndicator() 
        )
    )



Future fetchData() async
    final result = await Future.wait([...]);
    setState(() 
        stops = json.decode(result[0].body);
        marhe = json.decode(result[1].body);
        arrival = json.decode(result[2].body);
        isDataObtained = true;
    );

【讨论】:

以上是关于来自 API 请求的错误“在 null 上调用了方法 '[]'。接收方:null 尝试调用:[](0)”更新的主要内容,如果未能解决你的问题,请参考以下文章

来自 RESTful API 的发布请求给出 UnhandledPromiseRejectionWarning:ValidationError:产品验证失败:错误

来自 C#/.NET 服务的 Google Play Android Developer API - (400) 错误请求

使用来自 Angular JS 的 Web API 令牌身份验证时出现错误请求 (400)

Axios 请求 - 来自 PHP API 的 Gzip 数据

无法接收来自 Instagram API 的 POST 请求

Angular2 中的 Http PUT 到 .NET Core Web API 提供来自预检请求的 http 401 错误