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'] ?? ''}");
}
}
},
),
);
}
}