Search code examples
flutterflutter-layoutflutter-provider

Provider does not update a variable while fetching data


Firstly, I have a login screen and I want to change button with CircularProgressIndicator when button is clicked. I am using Provider to handle state management. Here is my Provider class.

class UserProvider with ChangeNotifier {
bool _loading = false;
bool get loading => _loading;
UserViewModel? user;
bool isLoggedOut = false;
TokenRequestModel tokenRequestModel = TokenRequestModel(
  username: '', password: '', environment: '', deviceToken: '');

login(TokenRequestModel requestModel) async {
  _loading = true;
  user = await UserService().login(requestModel);
  _loading = false;

  notifyListeners();
 }

}

I change loading value between my Api call. Then I want to catch it in my login screen to change widget. With that way I prevent button clicked multiple times and my login screen looks like this.

Column(
              children: [
                //textfield widgets

                context.watch<UserProvider>().loading == false
                    ? button(context, userProvider)
                    : Container(
                        height: 35.h,
                        width: 280.w,
                        decoration: BoxDecoration(color: blueLogo),
                        child: const CircularProgressIndicator(
                          color: Colors.white,
                        ),
                      )
              ],
            ),

I have tried multiple methods like Consumer, userProvider = Provider.of<UserProvider>(context); but nothing happens. What am I missing or what is the mistake of my method to handle state management? Would you help me to find right way to do? Thanks


Solution

  • Seems to me that you are notifying listeners when _loading has gone back to being false again, but you never notified them when it turned true!

    Try this, in your provider file:

    class UserProvider extends ChangeNotifier {
    bool _loading = false;
    bool get loading => _loading;
    UserViewModel? user;
    bool isLoggedOut = false;
    TokenRequestModel tokenRequestModel = TokenRequestModel(
      username: '', password: '', environment: '', deviceToken: '');
    
    login(TokenRequestModel requestModel) async {
      _loading = true;
      notifyListeners();  // <- The crucial line, right here!
    
      user = await UserService().login(requestModel);
      _loading = false;
      notifyListeners();
     }
    
    }
    

    I noticed you had used with ChangeNotifier instead of extends ChangeNotifier... but I don't know what that does! I always use extends ChangeNotifier and that works for me.