我正在使用登录API登录到我的应用程序,并且从登录API收到的响应中,我想调用另一个将填充主页上数据的API。
但是,当我尝试进行第二次API调用然后移至主页时。在API完成之前,它将移至第二页并提供空值。 (第二次API调用工作正常,并在一段时间后提供了请求数据)
我该如何解决?谢谢。
我的登录页面
import .....
class Login extends StatefulWidget{
final void Function(UserCredentials) onSignedIn;
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
var response;
//To save data from FIRST API to shared Pref
Future<bool> saveNamedPreference(String ID, String authid) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("ID", ID );
prefs.setString("authID", authid );
return await prefs.setBool("iDExist", true);
}
//
//To save data from SECOND API to shared Pref
Future<bool> saveUserPreference(String name, String role) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("name", name);
prefs.setString("role", role );
return await prefs.setBool("UserExists", true);
}
@override
Widget build(BuildContext context){
//SECOND API CALL
Future<int> saveUserDetails(String userID, String authID) async{
getUser(userID, authID).then((value){
final json = value;
if(json!="Error"){
User user = userFromJson(json);
saveUserPreference(user.username, user.role);
print('set the other values too ');
return 1;
}
else{
print('dint get proper json data ');
return 0;
}
});
}
//LOGIN API
Future<Map<String, dynamic>> getData() async {
var client = http.Client();
var response = await client
.post(
Uri.encodeFull(
'{url}'),
body:
{"email":"$username","password":"$password"}
).whenComplete(
client.close);
var res = json.decode(response.body);
if(response.statusCode <200 || response.statusCode > 400){
print("Error");
throwError();
}
if(response.statusCode == 200 ){
saveNamedPreference(res["userId"], res["id"]);;
UserCredentials uc = userCredentialsFromJson(response.body);
//Using then so that it shifts to Home only after func completion however its not happening
saveUserDetails(uc.userId, uc.id).then((value){
widget.onSignedIn(uc); //gives call back to root page to move to HOME
});
}
if (!mounted)
return {'success': false};
return json.decode(response.body);
}
;
Stack stack = Stack(
...... );
return Scaffold(
resizeToAvoidBottomPadding: false,
body: stack
);
}
}
在我的主页的init方法中,我正在访问Shared Pref的值(使用相同的async then方法),然后使用setState更新该值,但该值仍为空值。
答案 0 :(得分:0)
首先,将所有带有api调用的方法移至build
方法之外。
问题可能出在这里:
saveNamedPreference(res["userId"], res["id"]);
您不会等到此方法返回。 当您使用异步方法并要等待响应时,需要使用await。
我认为这段代码看起来要好得多...
import .....
class Login extends StatefulWidget {
final void Function(UserCredentials) onSignedIn;
@override
_LoginState createState() => _LoginState();
}
class _LoginState extends State<Login> {
var response;
//To save data from FIRST API to shared Pref
Future<bool> saveNamedPreference(String ID, String authid) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("ID", ID);
prefs.setString("authID", authid);
return await prefs.setBool("iDExist", true);
}
//To save data from SECOND API to shared Pref
Future<bool> saveUserPreference(String name, String role) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString("name", name);
prefs.setString("role", role);
return await prefs.setBool("UserExists", true);
}
//SECOND API CALL
Future<int> saveUserDetails(String userID, String authID) async {
final json = await getUser(userID, authID);
if (json != "Error") {
User user = userFromJson(json);
saveUserPreference(user.username, user.role);
print('set the other values too ');
return 1;
} else {
print('dint get proper json data ');
return 0;
}
}
//LOGIN API
Future<Map<String, dynamic>> getData() async {
var client = http.Client();
var response = await client
.post(
Uri.encodeFull('{url}'),
body: {"email": "$username", "password": "$password"}
);
var res = json.decode(response.body);
if (response.statusCode < 200 || response.statusCode > 400) {
print("Error");
throwError();
}
if (response.statusCode == 200) {
await saveNamedPreference(res["userId"], res["id"]);
UserCredentials uc = userCredentialsFromJson(response.body);
//Using then so that it shifts to Home only after func completion however its not happening
await saveUserDetails(uc.userId, uc.id);
widget.onSignedIn(uc); //gives call back to root page to move to HOME
}
if (!mounted) {
return {'success': false};
}
return json.decode(response.body);
}
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: false,
body: _buildStack(),
);
}
Widget _buildStack(){
return Stack(
......
);
}
}