8
votes

when I use setState () the text appears in the debug console..

setState() callback argument returned a Future. The setState() method on _LoginActivityState#9cd91 was called with a closure or method that returned a Future. Maybe it is marked as "async". Instead of performing asynchronous work inside a call to setState(), first execute the work (without updating the widget state), and then synchronously update the state inside a call to setState().

   Future<void> login() async {
final formState = formKey.currentState;
if (formState.validate()) {
  formState.save();
  try {
    final response = await UserController.login({
      "username": username,
      "password": password,
    });

    if (response != null && response["success"]) {
      setState(() async {
        accessToken = response['token'];
        //print(token);
        if (accessToken != null) {
          await Http.setAccessToken("Bearer $accessToken");
        }
        print('$accessToken');
        final getMe = await AiframeworkController.getProfile();
        print('data: $getMe');
        if (getMe != null && getMe['is_verified'] == true) {
           return Navigator.pushReplacement(
                context, MaterialPageRoute(builder: (context) => MainActivity()));
        } else {
          return Center(
                child: CircularProgressIndicator(),
              );
        }
      });
    }
  } catch (e) {
    print(e.message);
  }
}

}

1
You should probably do the async code outside of the setState method and only set the state when that code has completed - Smashing

1 Answers

6
votes

setState() should be used only to set the new state of a stateful widget. You shouldn't perform async operations in it and you shouldn't return anything from it. I am assuming that 'accessToken' is the field you are changing the state of so it will be better to do all of the other operations outside the setState() and just leave 'accessToken = response['token'];' inside.