Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flutter: State is lost on Hot Reload when using Provider

I am using Provider for managing the state of my app. Here's how I am implementing it.

hypnose.dart

class _HypnoseAppState extends State<HypnoseApp> {
  @override
  Widget build(BuildContext context) {
    UserService userService = UserService();
    AudioUtilService audioUtilService = AudioUtilService();

    return MultiProvider(
      providers: [
        ChangeNotifierProvider<UserService>.value(
          value: userService,
        ),
        ChangeNotifierProvider<AudioUtilService>.value(
          value: audioUtilService,
        )
      ],
      child: MaterialApp(
          debugShowCheckedModeBanner: false,
          title: Globals.title,
          theme: ThemeData(primarySwatch: Colors.cyan),
          darkTheme: ThemeData.dark(),
          initialRoute: '/',
          routes: {
            '/': (BuildContext context) => WelcomeScreen(userService),
            '/home': (BuildContext context) => HomePageSwitcher(),
            '/audiocreate': (BuildContext context) => AudioCreateScreen()
          }),
    );
  }
}

home_switcher.dart

class HomePageSwitcher extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Consumer<UserService>(
      builder: (BuildContext context, UserService userService, Widget child) {
        return Scaffold(
            appBar: AppBar(),
            drawer: Drawer(
              child: Column(
                children: <Widget>[
                  UserAccountsDrawerHeader(
                    accountEmail: Text(userService.loggedInUser.email),
                    accountName: Text(userService.loggedInUser.name),
                    currentAccountPicture:
                        Image.network(userService.loggedInUser.avatar),
                  )
                ],
              ),
            ),
            body: Center(
              child: RaisedButton(
                child: Text('Sign out'),
                onPressed: () async {
                  await userService.signOut();
                  Navigator.pushNamed(context, '/');
                },
              ),
            ));
      },
    );
  }
}

user_service.dart

class UserService extends ChangeNotifier {
  // Get auth instances
  final GoogleSignIn _googleSignIn = GoogleSignIn();
  final FirebaseAuth _auth = FirebaseAuth.instance;

  // Store reference of user collection
  final CollectionReference userDb = Firestore.instance.collection('user');

  // Master instance of logged in user
  User _loggedInUser;

  // Getter to access loggedInUser
  User get loggedInUser {
    return _loggedInUser;
  }

  PublishSubject<AuthState> _authStateSubject = PublishSubject();

.... other code

Now the problem here is that every time I hot reload, on the home page, I start to get the NoSuchMethodError as it says that properties like email, name etc. were called on null, which I think means that the state is lost. How can I overcome the same? Am I doing something wrong?

like image 444
Ayush Shekhar Avatar asked Jun 13 '19 12:06

Ayush Shekhar


People also ask

How to fix hot reload not working in flutter?

Problem with Hot Reload is one of them. Sometimes the Hot Reload may be disabled, deselected, inactive, not clickable or not proper workable. Solution is always depends the problem. Many reasons may cause the issue. This is the best solutions for your problem. First of all, uninstall the flutter. Select Flutter.

How to fix ‘hot reload’ not working in Android Studio?

Restart the android studio (IDE). Now the ‘Hot Reload’ button will be enabled. Save All option is also used instead of Hot Reload button. (Ctrl + S or File Save All) Method #3: Make sure your application is open and not closed by you after running.

What are the problems with hot reload?

Problem with Hot Reload is one of them. Sometimes the Hot Reload may be disabled, deselected, inactive, not clickable or not proper workable. Solution is always depends the problem.


1 Answers

You should not use ChangeNotifierProvider.value. Instead use the default constructor:

ChangeNotifierProvider(
  builder: (_) => UserService(),
)

Otherwise, your build method is impure and you'll have issues like described in How to deal with unwanted widget build?

like image 78
Rémi Rousselet Avatar answered Oct 04 '22 20:10

Rémi Rousselet