为什么 snapshot.data.length 会出错?
Why is there an error with snapshot.data.length?
我正在尝试解析来自 API 的数据。为此,我使用 FutureBuilder 在 ListView 中列出所有已解析的数据。
我已经对 snapshot.data
的无效性进行了检查,但我在段 snapshot.data.length
中不断收到此错误,它说 The property 'length' can't be unconditionally accessed because the receiver can be 'null'. Try making the access conditional (using '?.') or adding a null check to the target ('!').
我在 snapshot.data[i]
部分有一个类似的错误,它说 The method '[]' can't be unconditionally invoked because the receiver can be 'null'. Try making the call conditional (using '?.') or adding a null check to the target ('!').
这是我的代码的相同部分:
body: Container(
child: FutureBuilder(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
}else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, i) {
return ListTile(
title: snapshot.data[i].partOfSpeech,
);
});
}
},
),
),
这里是 getData(String s):
Future<List> getData(String s) async {
var response = await http
.get(Uri.https('api.dictionaryapi.dev', 'api/v2/entries/en_US/' + s));
var jsonData = jsonDecode(response.body)[0];
List<Data> data = [];
for (var x in jsonData["meanings"]) {
String definition = x["definitions"][0]["definition"];
Data d = Data(x["partOfSpeech"], definition);
data.add(d);
}
return data;
}
由于您正在检查 snapshot.data
不为空,因此您可以执行以下操作来修复它。
body: Container(
child: FutureBuilder(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
} else{
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, i) {
return ListTile(
title: snapshot.data[i]!.partOfSpeech,
);
});
}
},
),
),
你要看的是getData('hello')
的结果
显然,它不 return 长度为 属性 的东西。
继续 ,
我找到了解决问题的办法。显然 getData 没有按预期返回列表。相反,它返回一个对象。
类型转换 要列出的对象解决了问题。
这是更正后的代码:
body: Container(
child: FutureBuilder(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
}else{
//typecasting Object to List
var data = (snapshot.data as List<Data>).toList();
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, i) {
return ListTile(
title: data[i].partOfSpeech,
);
});
}
},
),
),
如果您使用的是新版本的 flutter(2.2.0 或更高版本)。首先尝试向目标添加空检查('!')。因为 null 安全功能。
body: Container(
child: FutureBuilder(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
}else{
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, i) {
return ListTile(
title: snapshot.data[i].partOfSpeech,
);
});
}
},
),
),
然后尝试将 FutureBuilder 类型指定为数据类型列表
body: Container(
child: FutureBuilder<List<Data>>(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
}else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, i) {
return ListTile(
title: snapshot.data[i].partOfSpeech,
);
});
}
},
),
),
在构建器参数中将 'AsyncSnapshot' 放在快照之前。
builder: (context, AsyncSnapshot snapshot)
我正在尝试解析来自 API 的数据。为此,我使用 FutureBuilder 在 ListView 中列出所有已解析的数据。
我已经对 snapshot.data
的无效性进行了检查,但我在段 snapshot.data.length
中不断收到此错误,它说 The property 'length' can't be unconditionally accessed because the receiver can be 'null'. Try making the access conditional (using '?.') or adding a null check to the target ('!').
我在 snapshot.data[i]
部分有一个类似的错误,它说 The method '[]' can't be unconditionally invoked because the receiver can be 'null'. Try making the call conditional (using '?.') or adding a null check to the target ('!').
这是我的代码的相同部分:
body: Container(
child: FutureBuilder(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
}else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, i) {
return ListTile(
title: snapshot.data[i].partOfSpeech,
);
});
}
},
),
),
这里是 getData(String s):
Future<List> getData(String s) async {
var response = await http
.get(Uri.https('api.dictionaryapi.dev', 'api/v2/entries/en_US/' + s));
var jsonData = jsonDecode(response.body)[0];
List<Data> data = [];
for (var x in jsonData["meanings"]) {
String definition = x["definitions"][0]["definition"];
Data d = Data(x["partOfSpeech"], definition);
data.add(d);
}
return data;
}
由于您正在检查 snapshot.data
不为空,因此您可以执行以下操作来修复它。
body: Container(
child: FutureBuilder(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
} else{
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, i) {
return ListTile(
title: snapshot.data[i]!.partOfSpeech,
);
});
}
},
),
),
你要看的是getData('hello')
显然,它不 return 长度为 属性 的东西。
继续
类型转换 要列出的对象解决了问题。
这是更正后的代码:
body: Container(
child: FutureBuilder(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
}else{
//typecasting Object to List
var data = (snapshot.data as List<Data>).toList();
return ListView.builder(
itemCount: data.length,
itemBuilder: (context, i) {
return ListTile(
title: data[i].partOfSpeech,
);
});
}
},
),
),
如果您使用的是新版本的 flutter(2.2.0 或更高版本)。首先尝试向目标添加空检查('!')。因为 null 安全功能。
body: Container(
child: FutureBuilder(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
}else{
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, i) {
return ListTile(
title: snapshot.data[i].partOfSpeech,
);
});
}
},
),
),
然后尝试将 FutureBuilder 类型指定为数据类型列表
body: Container(
child: FutureBuilder<List<Data>>(
future: getData('hello'),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Container(
child: Text("Loading"),
);
}else{
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, i) {
return ListTile(
title: snapshot.data[i].partOfSpeech,
);
});
}
},
),
),
在构建器参数中将 'AsyncSnapshot' 放在快照之前。
builder: (context, AsyncSnapshot snapshot)