3

I'm trying to get hold of Riverpod but I'm having some issues.

I created a form for signing in users and I'm trying to get the main view change when the user is logged in. My issue is, when I set change the state and navigate back to the app root, the new state doesn't seem to be available. But if I save a file or hot reload the app, the new state is available.

What I'm I doing wrong?

My main.dart file

import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:practical_riverpod/features/authenticated/authentication_state.dart';

import 'package:practical_riverpod/features/signup/signup_screen.dart';

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends ConsumerWidget {
  @override
  Widget build(BuildContext context, ScopedReader watch) {
    final auth = watch(authProvider).state;

    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceAround,
          children: [
            Text(auth == null ? "not connected" : auth.firstname),
            RaisedButton(
              child: Text("gooooo"),
              onPressed: () {
                Navigator.of(context).push(
                  MaterialPageRoute(
                    builder: (context) => SignupScreen(),
                  ),
                );
              },
            ),
          ],
        ),
      ),
    );
  }
}

I have a file with the state notifier inside:

import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:practical_riverpod/features/models/user_model.dart';

final authProvider = StateNotifierProvider((ref) {
  return AuthNotifier(null);
});

class AuthNotifier extends StateNotifier<UserModel> {
  AuthNotifier(UserModel state) : super(state);

  setCurrentUser(UserModel user) {
    state = user;
  }

  void clearUser() {
    state = null;
  }
}

the signup screen

import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:practical_riverpod/features/authenticated/authentication_state.dart';
import 'package:practical_riverpod/features/models/user_model.dart';

class SignupScreen extends HookWidget {
  @override
  Widget build(BuildContext context) {
    final _firstnameController =
        useTextEditingController.fromValue(TextEditingValue.empty);

    final _lastname =
        useTextEditingController.fromValue(TextEditingValue.empty);
    final GlobalKey<FormState> _key = GlobalKey<FormState>();

    final auth = context.read(authProvider);

    return Scaffold(
      body: Column(
        children: [
          SizedBox(
            height: 190,
          ),
          Container(
            padding: EdgeInsets.all(20),
            child: Column(
              children: [
                Text("Signup"),
                Form(
                  key: _key,
                  child: Column(
                    children: [
                      TextFormField(
                        decoration: InputDecoration(hintText: "Your email"),
                        controller: _firstnameController,
                        validator: (value) => _firstnameController.text.isEmpty
                            ? "Can't be empty"
                            : null,
                      ),
                      TextFormField(
                        obscureText: true,
                        onSaved: (newValue) => print(newValue),
                        validator: (value) =>
                            _lastname.text.isEmpty ? "Can't be empty" : null,
                        decoration: InputDecoration(
                          hintText: "Password",
                        ),
                        controller: _lastname,
                      ),
                      RaisedButton(
                        child: Text("Create"),
                        onPressed: () {
                          if (_key.currentState.validate()) {
                            auth.setCurrentUser(
                              UserModel(
                                  firstname: _firstnameController.text,
                                  lastname: "_password.text"),
                            );
                            Navigator.of(context).pop();
                          }
                        },
                      )
                    ],
                  ),
                )
              ],
            ),
          )
        ],
      ),
    );
  }
}

And finally my userModel:

class UserModel {
  final String firstname;
  final String lastname;

  UserModel({this.firstname, this.lastname});
}

1 Answer 1

3

[Riverpod >= 0.14.0] Change:

final auth = watch(authProvider).state;

to:

final auth = watch(authProvider);

[Riverpod < 0.14.0] Change:

final auth = watch(authProvider).state;

to:

final auth = watch(authProvider.state);

I would recommend adding a logger to your Riverpod ProviderScope - it can really help when debugging issues like this!

2
  • It works! Thank you! I'll spend more time on the documentation Commented Oct 1, 2020 at 4:48
  • Updated the answer to include the newest Riverpod syntax. Commented Apr 18, 2021 at 15:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.