Home > database >  flutter Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?'
flutter Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?'

Time:01-09

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 '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> {
  // String? one;
  // List? two;
  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()),
    );
  }
}

This is the error I received

: Error: Operator '[]' cannot be called on 'Map<dynamic, dynamic>?' because it is potentially null.
lib/dartpad.dart:41
 - 'Map' is from 'dart:core'.
      body: Text(three['id'].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

CodePudding user response:

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['id'], 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 ? 'Loading...' : three['id'].toString()),

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

CodePudding user response:

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("${three['id'] ?? ''}")

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

The recommended approach to call async function is using 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'] ?? ''}");
              }
          }
        },
      ),
    );
  }
}
  • Related