Home > Software engineering >  Change Notifier Provider with async function
Change Notifier Provider with async function

Time:07-02

I'm trying to use provider with an async function where I'm changing a value of variable and as soon as the value changes, I want all listeners to be notified.

I'm sending a post request and waiting for response in the below async function. I'm waiting for the response and depending on that I want to show message on the Stateful Widget.

The provider seems to change value of the variable but doesn't change state on Text on the screen.

userloginprovider.dart

bool isLoading = false;
HttpService http = HttpService();

class UserLoginProvider with ChangeNotifier {
  String loginMessage = '';
  late UserAuthorizationResponse userRegistrationResponse;

  Future loginUser(userData) async {
    Response response;

    print(loginMessage);
    try {
      isLoading = true;
      response = await http.loginUser('api/v1/login/', userData);
      isLoading = false;

      if (response.statusCode == 200) {
        var newReponse = response.data;
        userRegistrationResponse =
            UserAuthorizationResponse.fromJson(newReponse['data']);
        loginMessage = newReponse['message'];

      } else {
        print('status code is not 200.');
      }
    } on Exception catch (e) {
      isLoading = false;
      loginMessage = e.toString().substring(11);
    }    
    notifyListeners();
  }
}

userloginscreen.dart

class _LoginPageState extends State<LoginPage> {
  final UserLoginProvider userLoginProvider = UserLoginProvider();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: ChangeNotifierProvider(
        create: (context) => UserLoginProvider(),
        child: Consumer<UserLoginProvider>(
          builder: (context, provider, child) {
            return Container(
              padding: const EdgeInsets.all(8.0),
              width: double.infinity,
              height: double.infinity,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(provider.loginMessage.toString()), //<-- I want to change value here.
                  AuthorizationButtons(
                    fieldName: 'Username',
                    textEditingController: usernameController,
                  ),
                  AuthorizationButtons(
                    fieldName: 'Password',
                    textEditingController: passwordController,
                  ),
                  OutlinedButton(
                    onPressed: () {
                      userData = {
                        'username': usernameController.text,
                        'password': passwordController.text,
                      };
                      userLoginProvider.loginUser(userData);
                    },
                    child: const Text('Submit'),
                  )
                ],
              ),
            );
          },
        ),
      ),
    );
  }
}

CodePudding user response:

A new provider is created in every rebuild

      body: ChangeNotifierProvider(
        create: (context) => UserLoginProvider(),

Use the one in the state

      body: ChangeNotifierProvider(
        create: (context) => userLoginProvider,

CodePudding user response:

you are notifying the listeners when it fails which is in catch block:-

 on Exception catch (e) {
  isLoading = false;
  loginMessage = e.toString().substring(11); //here
  notifyListeners();
 }
}

but if the code runs without the error(exception). you are not notifying it on your code. so,if you want to notify, try something like this

 try {
  isLoading = true;
  response = await http.loginUser('api/v1/login/', userData);
  isLoading = false;

  if (response.statusCode == 200) {
    var newReponse = response.data;
    userRegistrationResponse =
        UserAuthorizationResponse.fromJson(newReponse['data']);
    loginMessage = 'something'; //here

  } else {
    print('status code is not 200.');
  }
   notifyListeners();//notify the listeners here
  • Related