I'm new and currently learning Flutter, I have a question about FutureBuilder. My code is stuck at ConnectionState.waiting and I'm not sure why.
My codes are
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> {
List three = [];
Future<dynamic> fetchData() async {
var sheetID = '1j7sYExCP0etGw_LoxqYTFRrjwHmJv73SHzC26jbtpH4';
var sheetTab = 'daftar';
var url = Uri.parse('https://opensheet.elk.sh/$sheetID/$sheetTab');
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: FutureBuilder<dynamic>(
future: fetchData(),
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return Text("${three[1]["nama"] ?? ''}");
}
}
},
),
);
}
}
I have tried to delete
case ConnectionState.waiting:
return Text('Loading....');
But received an error.
I have also tried to changed .hasData
on snapshot (suggested from other thread) but the editor did not accept it.
I tried to not use switch
and direcly used if
but received RangeError (RangeError (index): Invalid value: Valid value range is empty: 1)
error.
I want to run three[1]["nama"]
(preferably in loop so I can display the rest of the data)
Thank you!
CodePudding user response:
The reason this happened is that you are not return anything in fetchData
, change fetchData
to this:
Future<dynamic> fetchData() async {
var sheetID = '1j7sYExCP0etGw_LoxqYTFRrjwHmJv73SHzC26jbtpH4';
var sheetTab = 'daftar';
var url = Uri.parse('https://opensheet.elk.sh/$sheetID/$sheetTab');
http.Response response;
response = await http.get(url);
return json.decode(response.body);
}
then define new variable like this:
Future fetchFuture;
then use it like this inside initState
:
@override
void initState() {
super.initState();
fetchFuture = fetchData();
}
then change your last return in your builder to this:
FutureBuilder<dynamic>(
future: fetchFuture,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return Text('Loading....');
default:
if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
List data = snapshot.data ?? [];
return Text("${data[1]["nama"] ?? ''}");
}
}
},
)
CodePudding user response:
- There is nothing wrong with your code, it is your own mistake
Text("${three[1]["nama"] ?? ''}")
// Does your List really have two values?
// Is the Key value really 'nama'? Are you sure it's not a name?