Flutter FutureBuilder 返回空数据
Flutter FutureBuilder returning null data
我是 Flutter 和 Dart 的新手,我正在尝试编写一个应用程序来测试它。
我有一个 api,我正在获取应用程序的数据,并尝试使用 StatefulWidget 和 FutureBuilder。
当我 运行 调用 api 的方法时,我得到了结果(使用 print() 对其进行测试),但是当我从 loadData 方法获取数据时,它返回 null。
因此 loadData 打印数据,initState 和 FutureBuilder 打印数据 returns null。我在这里错过了什么。
我已经添加了用于请求的服务和模型...希望对您有所帮助。
Future<CoachesModelRes> loadData(Profile _profile) async {
await getPost(_profile.getToken()).then((response) {
if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
return coaches;
} else {
return null;
}
} else {
String code = response.statusCode.toString();
return null;
}
}).catchError((error) {
print(error.toString());
return null;
});
}
@override
void initState() {
super.initState();
print(widget.profile.getToken());
data = loadData(widget.profile);
data.then((data_) async {
var cenas = data_.count;
print("asdasd $cenas");
});
}
Future<CoachesModelRes> data;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: appWhiteColor,
appBar: applicationBar(),
drawer: adminDrawer(widget.profile, AdminDrawerListEnum.coaches, context),
body: FutureBuilder<CoachesModelRes>(
future: data,
builder: (context, snapshot) {
//print(snapshot.data.count.toString());
if (snapshot.hasData) {
return Text("nop");
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Text("nop");
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
);
}
Future<http.Response> getPost(String token) async {
final response = await http.get(new Uri.http("$apiUrl", "$coachesEndPoint"),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.authorizationHeader : 'Bearer $token'
},
);
return response;
}
CoachesModelRes postFromJson(String str) => CoachesModelRes.fromJson(json.decode(str));
class CoachesModelRes {
int count;
List<CoachModelRes> coaches;
CoachesModelRes({
this.count,
this.coaches,
});
factory CoachesModelRes.fromJson(Map<String, dynamic> json) => new CoachesModelRes(
count: json["count"],
coaches: (json["coaches"] as List).map((i) => CoachModelRes.fromJson(i)).toList(),
);
}
CoachModelRes postFromJson(String str) => CoachModelRes.fromJson(json.decode(str));
class CoachModelRes {
String id;
String firstName;
String lastName;
String description;
String username;
String notes;
List<String> roles;
CoachModelRes({
this.id,
this.firstName,
this.lastName,
this.description,
this.username,
this.notes,
this.roles,
});
factory CoachModelRes.fromJson(Map<String, dynamic> json) => new CoachModelRes(
id: json["id"],
firstName: json["firstName"],
lastName: json["lastName"],
description: json["description"],
username: json["username"],
notes: json["notes"],
roles: new List<String>.from(json["roles"]),
);
}
Future<CoachesModelRes> loadData(Profile _profile) async {
final response = await getPost(_profile.getToken());
try{if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
return coaches;
} else {
return null;
}
} else {
String code = response.statusCode.toString();
return null;
}}catch(e){
return null ;
}
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: appWhiteColor,
appBar: applicationBar(),
drawer: adminDrawer(widget.profile, AdminDrawerListEnum.coaches, context),
body: FutureBuilder<CoachesModelRes>(
future: loadData(widget.profile),
builder: (context, snapshot) {
//print(snapshot.data.count.toString());
if (snapshot.hasData) {
return Text("nop");
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Text("nop");
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
);
}
这里的问题是 return 语句应该在方法的末尾。
因为getPost
会return数据到loadData
。
并且当 getPost
完成时 loadData
将 return 数据发送到调用他的方法。
在我的例子中,loadData
没有 returning 任何东西,所以 FutureBuilder
中的 snapshot
总是空的。
按道理现在是这样的,但当时想不通:\
Future<CoachesModelRes> loadData(Profile _profile) async {
// So I need to create a variable to return
CoachesModelRes response;
//-----
await getPost(_profile.getToken()).then((response) {
if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
// Set the variable value
response = coaches;
//-----
} else {
// Set the variable value
response = null;
//-----
}
} else {
String code = response.statusCode.toString();
// Set the variable value
response = null;
//-----
}
}).catchError((error) {
print(error.toString());
// Set the variable value
response = null;
//-----
});
// And at the end return the response variable
return response;
//-----
}
我是 Flutter 和 Dart 的新手,我正在尝试编写一个应用程序来测试它。 我有一个 api,我正在获取应用程序的数据,并尝试使用 StatefulWidget 和 FutureBuilder。
当我 运行 调用 api 的方法时,我得到了结果(使用 print() 对其进行测试),但是当我从 loadData 方法获取数据时,它返回 null。
因此 loadData 打印数据,initState 和 FutureBuilder 打印数据 returns null。我在这里错过了什么。
我已经添加了用于请求的服务和模型...希望对您有所帮助。
Future<CoachesModelRes> loadData(Profile _profile) async {
await getPost(_profile.getToken()).then((response) {
if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
return coaches;
} else {
return null;
}
} else {
String code = response.statusCode.toString();
return null;
}
}).catchError((error) {
print(error.toString());
return null;
});
}
@override
void initState() {
super.initState();
print(widget.profile.getToken());
data = loadData(widget.profile);
data.then((data_) async {
var cenas = data_.count;
print("asdasd $cenas");
});
}
Future<CoachesModelRes> data;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: appWhiteColor,
appBar: applicationBar(),
drawer: adminDrawer(widget.profile, AdminDrawerListEnum.coaches, context),
body: FutureBuilder<CoachesModelRes>(
future: data,
builder: (context, snapshot) {
//print(snapshot.data.count.toString());
if (snapshot.hasData) {
return Text("nop");
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Text("nop");
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
);
}
Future<http.Response> getPost(String token) async {
final response = await http.get(new Uri.http("$apiUrl", "$coachesEndPoint"),
headers: {
HttpHeaders.contentTypeHeader: 'application/json',
HttpHeaders.authorizationHeader : 'Bearer $token'
},
);
return response;
}
CoachesModelRes postFromJson(String str) => CoachesModelRes.fromJson(json.decode(str));
class CoachesModelRes {
int count;
List<CoachModelRes> coaches;
CoachesModelRes({
this.count,
this.coaches,
});
factory CoachesModelRes.fromJson(Map<String, dynamic> json) => new CoachesModelRes(
count: json["count"],
coaches: (json["coaches"] as List).map((i) => CoachModelRes.fromJson(i)).toList(),
);
}
CoachModelRes postFromJson(String str) => CoachModelRes.fromJson(json.decode(str));
class CoachModelRes {
String id;
String firstName;
String lastName;
String description;
String username;
String notes;
List<String> roles;
CoachModelRes({
this.id,
this.firstName,
this.lastName,
this.description,
this.username,
this.notes,
this.roles,
});
factory CoachModelRes.fromJson(Map<String, dynamic> json) => new CoachModelRes(
id: json["id"],
firstName: json["firstName"],
lastName: json["lastName"],
description: json["description"],
username: json["username"],
notes: json["notes"],
roles: new List<String>.from(json["roles"]),
);
}
Future<CoachesModelRes> loadData(Profile _profile) async {
final response = await getPost(_profile.getToken());
try{if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
return coaches;
} else {
return null;
}
} else {
String code = response.statusCode.toString();
return null;
}}catch(e){
return null ;
}
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: appWhiteColor,
appBar: applicationBar(),
drawer: adminDrawer(widget.profile, AdminDrawerListEnum.coaches, context),
body: FutureBuilder<CoachesModelRes>(
future: loadData(widget.profile),
builder: (context, snapshot) {
//print(snapshot.data.count.toString());
if (snapshot.hasData) {
return Text("nop");
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
return Text("nop");
// By default, show a loading spinner.
return CircularProgressIndicator();
},
),
);
}
这里的问题是 return 语句应该在方法的末尾。
因为getPost
会return数据到loadData
。
并且当 getPost
完成时 loadData
将 return 数据发送到调用他的方法。
在我的例子中,loadData
没有 returning 任何东西,所以 FutureBuilder
中的 snapshot
总是空的。
按道理现在是这样的,但当时想不通:\
Future<CoachesModelRes> loadData(Profile _profile) async {
// So I need to create a variable to return
CoachesModelRes response;
//-----
await getPost(_profile.getToken()).then((response) {
if (response.statusCode == 200) {
CoachesModelRes coaches = coachesModel.postFromJson(response.body);
if (coaches.count > 0) {
print(coaches.count);
print(coaches.coaches[0].description);
// Set the variable value
response = coaches;
//-----
} else {
// Set the variable value
response = null;
//-----
}
} else {
String code = response.statusCode.toString();
// Set the variable value
response = null;
//-----
}
}).catchError((error) {
print(error.toString());
// Set the variable value
response = null;
//-----
});
// And at the end return the response variable
return response;
//-----
}