Search code examples
flutterflutter-provider

Widgets don't rebuild when state changes in provider


Thing that I'm looking for is that a BottomNavigationBarItem change when user logs in to the app. I've created a provider service for this.

class UserData with ChangeNotifier, DiagnosticableTreeMixin {
  bool _isLoggedin = false;
  bool get isLoggedin => _isLoggedin;
  UserData() {
    print('UserData Provider is summoned!');
    loginState();
  }
    void loginStateSetter(bool val) {
    this._isLoggedin = val;
    print("Login State changed to ${this._isLoggedin}");
    notifyListeners();
  }
  void loginState() async {
    this._isLoggedin = await wooCommerceCredentials.isCustomerLoggedIn();
    print('loginState() func called. login state is ${this._isLoggedin}');
    notifyListeners();
  }
}

Based on that I see on debug console, the logging process happens without a problem and error. After each successful login I set the _isLoggedin value using loginStateSetter function. (And this happens successfully too.) But the problem that I face is that widgets don't rebuild themselves. And I don't understand why. The value inside provider changes successfully, shouldn't that rebuild the widgets? The code insinde bottomNavigationBar widget:

Provider.of<UserData>(context).isLoggedin
              ? BottomNavigationBarItem(
                  activeIcon: Icon(Icons.account_circle),
                  icon: Icon(Icons.account_circle_outlined),
                  label: 'Profile',
                )
              : BottomNavigationBarItem(
                  activeIcon: Icon(Icons.account_circle),
                  icon: Icon(Icons.account_circle_outlined),
                  label: 'Login/Sign up',
                ),
        

Note: Login happens inside another page in which provider has been summoned like this inside drawer:

ListTile(
            leading: Icon(Icons.account_circle_outlined),
            title: Text('Login / Sign Up',
                style: TextStyle(fontWeight: FontWeight.normal)),
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(
                    builder: (context) => ChangeNotifierProvider(
                        child: LoginPage(), create: (_) => UserData())),
              );
            },
          ),

What should I change? I've tried using StreamBuilder and such (outside buttom menu) but widgets don't rebuild until I hot restart. What am I doing wrong?


Solution

  • The issue was caused by calling the provider twice. After removing second provider from the widget tree, it started to rebuild the widgets as intended to.