我正在尝试从 Flutter 中的 API 获取数据。只是为了测试我使用的 API URL:https://jsonplaceholder.typicode.com/todos/1 它具有以下 JSON 对象:
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
我按照网上的一个示例进行了几乎完全的调整以匹配我想要的工作流程,但下面的
snapshot.hasData
返回 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());
}
},
),
),
);
}
}
返回的是模拟器屏幕上的
CircularProgressIndicator()
,表明 snapshot.hasData
为 false。我在控制台中没有收到任何错误或任何错误,所以我不知道如何继续。
---编辑--- 根据评论者的建议对上面的代码进行了更改:
将返回类型从
更改为Future<List<dynamic>>
,并将Future<Map<String, dynamic>>
更改为return json.decode(result.body)['results'];
。return json.decode(result.body)
现在我收到以下错误:
构建时抛出以下 NoSuchMethodError FutureBuilder
在 null 上调用方法“[]”。接收者:空
尝试拨打:[](“标题”)
API 响应是一个 JSON 对象
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
且仅包含
userId
、id
、title
和 completed
成员
请考虑从对象中获取,而不是引用索引。
更换
snapshot.data[index]
与
snapshot.data
还有
snapshot.data['picture']['large']
您的 JSON 对象中没有
picture
数据,请尝试注释该代码或向其中添加图片
在检查 hasData 之前,执行以下操作:
if (snapshot.connectionState == ConnectionState.done) {
// your code
}
编辑
您的要求
var result = await http.get(apiUrl+accountNum);
返回 JSON 对象而不是 JSON 列表。但是在将其更新为 Future> 之前,您的 fetchData
Future<Map<String, dynamic>> fetchData() async {
var result = await http.get(apiUrl+accountNum);
return json.decode(result.body);
}
不需要 json.decode(result.body)['results'],因为您只获取对象而不是列表。
改变
title: Text(_MeterNum(snapshot.data[index])),
subtitle: Text(_MeterNum(snapshot.data[index])),
trailing: Text(_MeterNum(snapshot.data[index])),
到
title: Text(_MeterNum(snapshot.data)),
subtitle: Text(_MeterNum(snapshot.data)),
trailing: Text(_MeterNum(snapshot.data)),
没有 ['picture']['large'] 这样的键,所以在 ListTile
中注释掉该键