River_pod: Listening to selected states of StateNotifierProvider

Created on 13 Oct 2020  路  5Comments  路  Source: rrousselGit/river_pod

Hey Remi 馃憢
Got a question for you :)

I am having a scenario where I have a freezed union which is a state of StateNotifier.
In 2 of possible states, there is a field I want to expose in another provider.

final channelProvider = StateProvider<Channel>((ref) {
  final state = ref.watch(sendbirdServiceProvider.state);
  return state.maybeWhen(
    channelChosen: (_, channel) => channel,
    messagesLoaded: (_, channel, __) => channel,
    orElse: () => null, //Use previous state (don't rebuild) if possible
  );
});

And this works.
Although I wish to know if it's possible to conditionally return the previous instance of a provider instead of creating a new one?
Basically in orElse I would like to return a cached channel if it's possible.

The other way to approach it is to watch for only specific states of stateNotifierProvider which contain channel I want to expose and don't cause rebuilds in other scenarios. Is any of those possible?

Thank you 馃挋

documentation

Most helpful comment

For now you can do:

final example = StateNotifierProvider<StateController<Channel>>((ref) {
  final notifier = StateController<Channel>();

  final sendbird = ref.watch(sendbirdServiceProvider);
  final removeListener = sendbird.addListener((value) {
    notifier.state = value.channel;
  });
  ref.onDispose(removeListener);

  return notifier;
});

All 5 comments

Your channel can be null.

return state.maybeWhen(
    channelChosen: (_, channel) => channel,
    messagesLoaded: (_, channel, __) => channel,
    orElse: () => null, //Use previous state (don't rebuild) if possible
  );

orElse might be the first thing to be called in this statement and if not, why do you expose more than channelChosen and messagesLoaded?

orElse might be the first thing to be called in this statement

Yeah, I know I can't always prevent it but accessing the previous state would be great with all the non-first scenarios.

That's a case I'm working on

I'm thinking of two things:

ref.listen<T>(myProvider, (value) {
  print(value);
});

as an alternative to ref.watch, as your typical onChange (but without having to care about removing the listener).

Then combined with ref.setState(newState)

So we'd have

final example = StateProvider<Model>((ref) {
  ref.listen<Another>(another, (value) {
    ref.setState(<whatever>);
  });
});

For now you can do:

final example = StateNotifierProvider<StateController<Channel>>((ref) {
  final notifier = StateController<Channel>();

  final sendbird = ref.watch(sendbirdServiceProvider);
  final removeListener = sendbird.addListener((value) {
    notifier.state = value.channel;
  });
  ref.onDispose(removeListener);

  return notifier;
});

Thank you! <3

Was this page helpful?
0 / 5 - 0 ratings