Riverpod FutureProvider - passing result between screens

278 Views Asked by At

I'm learning Riverpod provider and stuck on a topic regarding passing values between screens.

As I learnt from Riverpod docs - it delivers a provider that enables values to be accessed globally... and here is my case.

I'm creating a service repo, that contains some methods delivering futures (e.g. network request to verify user):

class VerifyUser {

  Future<User> verifyUser(String input) async {

    await Future.delayed(const Duration(seconds: 2));

    print(input);

    if (input == 'Foo') {
      print('Foo is fine - VERIFIED');
      return User(userVerified: true);
    } else {
      print('$input is wrong - NOT VERIFIED');
      return User(userVerified: false);
    }
  }
}

Next step is to create providers - I'm using Riverpod autogenerate providers for this, so here are my providers:

part 'providers.g.dart';

@riverpod
VerifyUser verifyUserRepo(VerifyUserRepoRef ref) {
  return VerifyUser();
}

@riverpod
Future<User> user(
    UserRef ref,
    String input
    ) {
  return ref
      .watch(verifyUserRepoProvider)
      .verifyUser(input);
}

and there is a simple User model for this:

class User {

  bool userVerified;

  User({required this.userVerified});

}

I'm creating a wrapper, that should take the user to Homescreen, when a user is verified, or take the user to authenticate screen when a user is not verified.

class Wrapper extends ConsumerWidget {

  @override
  Widget build(BuildContext context, WidgetRef ref) {

    String user = '';
    final userFromProvider = ref.watch(userProvider(user));

    if (user == 'verified') {
      print(userFromProvider);
      return MyHomePage();
    } else {
      return Authenticate();
    }
  }
}

App opens on Authenticate screen because there is no info about the user.

On Authenticate screen I'm getting input and passing it to FutureProvider for verification.

final vUser = ref.watch(userProvider(userInput.value.text));

When I'm pushing to Wrapper and calling provider - I'm not getting the value I initially got from future.

ElevatedButton(
     onPressed: () async {
     vUser;
     if (vUser.value?.userVerified == true) {
         print('going2wrapper');
         Navigator.of(context).push(MaterialPageRoute(builder: (context) => Wrapper()));
      }},
     child: const Text('Verify User'))

Inside Wrapper it seems that this is only thing that I can do:

String user = '';
final userFromProvider = ref.watch(userProvider(user));

But it makes me call the provider with a new value... and causing unsuccessful verification and I cannot proceed to homescreen.

As a workaround, I see that I can pass the named argument to Wrapper, but I want to use the provider for it... is it possible?

I hope that there is a solution to this.

Thx! David

0

There are 0 best solutions below