flutter错误:无法在`Map?`上调用运算符`[]`,因为它可能为空。

huangapple go评论91阅读模式
英文:

flutter Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null

问题

以下是您的翻译:

我是Flutter的新手,一直在浏览Stackoverflow。最近,我遇到了一个从URL获取数据的问题,即使阅读了也无法理解。

这是我的代码:

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

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

  @override
  State<DartPad> createState() => _DartPadState();
}

class _DartPadState extends State<DartPad> {
  Map? three;

  Future fetchData() async {
    var url = Uri.parse('https://www.thegrowingdeveloper.org/apiview?id=2');
    http.Response response;
    response = await http.get(url);
    setState(() {
      three = json.decode(response.body);
    });
  }

  @override
  void initState() {
    fetchData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        centerTitle: true,
        title: const Text('Dartpad'),
      ),
      body: Text(three['id'].toString()),
    );
  }
}

这是我收到的错误:

错误:无法在 'Map<dynamic, dynamic>?' 上调用运算符 '[]',因为它可能为null
lib/dartpad.dart:41
 - 'Map' 来自 'dart:core'
      body: Text(three['id'].toString()),
                      ^

我不太明白这个错误出现的原因以及如何修复它。有人可以帮助我吗?

我尝试添加 '!' 但仍然不起作用。

英文:

I am new to Flutter and had been browsing through Stackoverflow. I recently encounter a problem with fetch data from URL and unable to understand even after reading it.

This is my code

import &#39;dart:convert&#39;;
import &#39;package:flutter/material.dart&#39;;
import &#39;package:http/http.dart&#39; as http;

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

  @override
  State&lt;DartPad&gt; createState() =&gt; _DartPadState();
}

class _DartPadState extends State&lt;DartPad&gt; {
  // String? one;
  // List? two;
  Map? three;

  Future fetchData() async {
    var url = Uri.parse(&#39;https://www.thegrowingdeveloper.org/apiview?id=2&#39;);
    http.Response response;
    response = await http.get(url);
    setState(() {
      three = json.decode(response.body);
    });
  }

  @override
  void initState() {
    fetchData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        centerTitle: true,
        title: const Text(&#39;Dartpad&#39;),
      ),
      body: Text(three[&#39;id&#39;].toString()),
    );
  }
}

This is the error I received

: Error: Operator &#39;[]&#39; cannot be called on &#39;Map&lt;dynamic, dynamic&gt;?&#39; because it is potentially null.
lib/dartpad.dart:41
 - &#39;Map&#39; is from &#39;dart:core&#39;.
      body: Text(three[&#39;id&#39;].toString()),
                      ^

I don't quite understand where this error is coming and how to fix it. Can someone help me?

I tried adding ! and it still doesn't work

答案1

得分: 1

这是由于null-safety问题引起的,请尝试给它添加默认值,首先像这样定义你的three

Map three = {};

然后像这样使用它:

Text("${three['id'] ?? ''}")

当你等待fetchData获取其结果时,UI构建,同时three为空,当它尝试从中获取['id']时,会抛出异常。

推荐的方法来调用async函数是使用FutureBuilder

class _DartPadState extends State<DartPad> {
  Future<Map> fetchData() async {
    var url = Uri.parse('https://www.thegrowingdeveloper.org/apiview?id=2');
    http.Response response;
    response = await http.get(url);
    return json.decode(response.body);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        centerTitle: true,
        title: const Text('Dartpad'),
      ),
      body: FutureBuilder<Map>(
        future: fetchData(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return Text('Loading....');
            default:
              if (snapshot.hasError) {
                return Text('Error: ${snapshot.error}');
              } else {
                Map three = snapshot.data ?? {};

                return Text("${three['id'] ?? ''}");
              }
          }
        },
      ),
    );
  }
}
英文:

This happened because of the null-safety issue, try add default value to it, first define your three like this:

Map three = {};

then use it like this:

Text(&quot;${three[&#39;id&#39;] ?? &#39;&#39;}&quot;)

when you holding for fetchData to get its result, ui builds and meanwhile, three is null and when it try to get [&#39;id&#39;] from it, through an exception.

The recommended approach to call async function is using FutureBuilder:

class _DartPadState extends State&lt;DartPad&gt; {
  Future&lt;Map&gt; fetchData() async {
    var url = Uri.parse(&#39;https://www.thegrowingdeveloper.org/apiview?id=2&#39;);
    http.Response response;
    response = await http.get(url);
    return json.decode(response.body);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        centerTitle: true,
        title: const Text(&#39;Dartpad&#39;),
      ),
      body: FutureBuilder&lt;Map&gt;(
        future: fetchData(),
        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.waiting:
              return Text(&#39;Loading....&#39;);
            default:
              if (snapshot.hasError) {
                return Text(&#39;Error: ${snapshot.error}&#39;);
              } else {
                Map three = snapshot.data ?? {};

                return Text(&quot;${three[&#39;id&#39;] ?? &#39;&#39;}&quot;);
              }
          }
        },
      ),
    );
  }
}

答案2

得分: 1

three 变量的类型是 Map?Map 后面的 ? 表示变量的值可以是 Mapnull

你不能读取 null['id'],而且 Flutter 不知道 Map 是否为 null。

为了解决这个问题,你有很多选项,具体取决于你想要做什么,以下是一种可能性:

body: Text(three == null ? 'Loading...' : three['id'].toString()),

这样,当 three 为 null 时,你将获得一个显示 Loading... 的文本。

英文:

The three variable has a type of Map?. The ? after Map means that the value of the variable can be either Map or null.

You can't read null[&#39;id&#39;], and flutter doesn't know weather Map is or isn't null yet.

To fix this, you have many options depending on what you want to do, here is a possibility:

body: Text(three == null ? &#39;Loading...&#39; : three[&#39;id&#39;].toString()),

This way, you will get a Loading... text while three is null

huangapple
  • 本文由 发表于 2023年1月9日 00:49:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75049628.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定