7

I want to use go_router (https://pub.dev/packages/go_router#redirection) together with Riverpod.

I have a Provider and a StreamProvider, which I would like to combine into a Listenable so it can be used as the refreshListenable param of GoRouter.

I guess I need combine the Provider and a StreamProvider into some kind of Provider (how?).

What is the easiest way to create a Listenable from a Provider?

Edit: I understand that this 'negates' the point of Riverpod, but the app is all setup with Riverpod already and I would just like to add go_router.

imi kim
  • 325
  • 2
  • 11

3 Answers3

4

There is a much simpler way as ChangeNotifier can be used with Riverpod. There is a Gihtub issue on Riverpod's Github repo on this. https://github.com/rrousselGit/river_pod/issues/884

Answered by Tim Whitting on Gihtub (his code and comments below):

You can use ChangeNotifier with flutter_riverpod.

final myNotifierProvider = ChangeNotifierProvider<MyNotifier>((ref) => MyNotifier());
class MyNotifier with ChangeNotifier {
  void refresh(){
    notifyListeners();
  }
}

Then you have to watch the provider where you are trying to pass the Listenable.

// 1.0.0-dev riverpod
refreshListenable: ref.watch(myNotifierProvider)
// 0.14.0
refreshListenable: watch(myNotifierProvider) // using a Consumer / ConsumerWidget

And use elsewhere

// 1.0.0-dev riverpod
ref.read(myNotifierProvider.notifier).refresh();
// 0.14.0
context.read(myNotifierProvider.notifier).refresh();
mLstudent33
  • 1,033
  • 3
  • 14
  • 32
  • 1
    Is there a way to do so using StateNotifier instead of ChangeNotifier ? I tried to do so, but couldn't make it work – GitGud31 Dec 09 '21 at 11:36
2

I solved it as follows:

class AListenable extends ValueNotifier {
  AListenable(value) : super(value);

  void changeValue(newValue) {
    value = newValue;
  }
}

   
 final aListenableInstance = AListenable(false);

 final myProvider = Provider((ref) {

  final my2ndProviderValue = ref.watch(my2ndProvider);

  if (my2ndProviderValue is AsyncError || my2ndProviderValue is AsyncLoading) {
    aListenableInstance.changeValue(false);
    return false;
  }

  aListenableInstance.changeValue(true);
  return true;
});

final _router = GoRouter(
    refreshListenable: aListenableInstance,...);
imi kim
  • 325
  • 2
  • 11
0

If you want to use the riverpod intensively, you can navigate with it directly, without go_router. There is interesting issue here: river_pod issues 1122

Pavel Zika
  • 128
  • 4