Cannot fetch data from api, Future always returns null - flutter
Solution 1
The API response is a JSON object
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
and contains only userId
,id
, title
and completed
memebers
instead of referring to an index please consider getting from the object.
replace
snapshot.data[index]
with
snapshot.data
also
snapshot.data['picture']['large']
you don't have picture
data in the JSON object, Try to comment that code or add a picture to it
Solution 2
Before checking for hasData do this:
if (snapshot.connectionState == ConnectionState.done) {
// your code
}
EDIT
Your request
var result = await http.get(apiUrl+accountNum);
returns JSON object not JSON List. But your fetchData method's return type was List before you updated it to Future<Map<String, dynamic>>. Write your method like this
Future<Map<String, dynamic>> fetchData() async {
var result = await http.get(apiUrl+accountNum);
return json.decode(result.body);
}
NO NEED FOR json.decode(result.body)['results'], because you are only fetching an object not a list.
Solution 3
change
title: Text(_MeterNum(snapshot.data[index])),
subtitle: Text(_MeterNum(snapshot.data[index])),
trailing: Text(_MeterNum(snapshot.data[index])),
to
title: Text(_MeterNum(snapshot.data)),
subtitle: Text(_MeterNum(snapshot.data)),
trailing: Text(_MeterNum(snapshot.data)),
there was no key as ['picture']['large'] so comment out the that key in ListTile
Kristin Vernon
Bachelor's Degree in Information Technology, Aspiring Masters student
Updated on December 29, 2022Comments
-
Kristin Vernon over 1 year
I'm trying to fetch data from an API in a flutter. Just to test I was using the API URL: https://jsonplaceholder.typicode.com/todos/1 which has the following JSON object:
{ "userId": 1, "id": 1, "title": "delectus aut autem", "completed": false }
I followed an example online almost exactly just tweaked to match the workflow I want but the
snapshot.hasData
below returns false.class Home extends StatelessWidget { final String accountNum; Home(this.accountNum); final String apiUrl = "https://jsonplaceholder.typicode.com/todos/"; Future<Map<String, dynamic>> fetchData() async { //accountNum below is passed from a previous screen, in this case I pass '1' //I printed it to make sure that '1' is passed and it is correct var result = await http.get(apiUrl+accountNum); //I printed the below and it also gave me the json from the api //print(json.decode(result.body)); return json.decode(result.body); } String _MeterNum(dynamic account){ return account['title']; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Account Data'), ), body: Container( child: FutureBuilder<Map<String, dynamic>>( future: fetchData(), builder: (BuildContext context, AsyncSnapshot snapshot) { if(snapshot.hasData){ print(_MeterNum(snapshot.data[0])); return ListView.builder( padding: EdgeInsets.all(8), itemCount: snapshot.data.length, itemBuilder: (BuildContext context, int index){ return Card( child: Column( children: <Widget>[ ListTile( leading: CircleAvatar( radius: 30, backgroundImage: NetworkImage(snapshot.data[index]['picture']['large'])), //I realize this will just show the same thing //but I was just keeping the format of the example I was following title: Text(_MeterNum(snapshot.data[index])), subtitle: Text(_MeterNum(snapshot.data[index])), trailing: Text(_MeterNum(snapshot.data[index])), ) ], ), ); }); }else { return Center(child: CircularProgressIndicator()); } }, ), ), ); } }
What is returned is the
CircularProgressIndicator()
to the emulator screen indicating thatsnapshot.hasData
is false. I don't get any error in the console or anything so I'm not sure how to proceed.---EDIT--- Made changes to the code above using suggestions from the commenters:
Changed return type from Future<List> to Future<Map<String, dynamic>> and changed 'return json.decode(result.body)['results'];' to 'return json.decode(result.body)'
And now I get the following error:
The following NoSuchMethodError was thrown building FutureBuilder<Map<String, dynamic>>(dirty, state: _FutureBuilderState<Map<String, dynamic>>#a10d4):
The method '[]' was called on null. Receiver: null
Tried calling:[] ("title")