riverpod icon indicating copy to clipboard operation
riverpod copied to clipboard

How to listen to Provider assignment not Provider value change

Open stephane-archer opened this issue 11 months ago • 6 comments

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:zero_loss_compress/convertion_stats.dart';

final batchSizeProvider = NotifierProvider<BatchSizeNotifier, int>(() {
  return BatchSizeNotifier();
});

final progressProvider = NotifierProvider<ProgressNotifier, int>(() {
  return ProgressNotifier();
});

class BatchSizeNotifier extends Notifier<int> {
  @override
  int build() {
    return 0;
  }

  void setBatchSizeAndResetConversionState(int batchSize) {
    state = batchSize;
    ref.read(progressProvider.notifier).reset();
    ref.read(convertionStatsStateProvider.notifier).reset();
  }
}

class ProgressNotifier extends Notifier<int> {
  @override
  int build() {
    return 0;
  }

  void increment() {
    state = state + 1;
  }

  void reset() {
    state = 0;
  }
}

What is the proper way to modify ProgressNotifier to listen to batchSizeProvider and to reset itself when BatchSizeNotifier changes, rather than let BatchSizeNotifier call the reset function?

Is there any documentation about how to properly listen to providers from other Notifiers? (it not maybe create one)

stephane-archer avatar Dec 14 '24 17:12 stephane-archer

Are you looking for ref.watch?

class ProgressNotifier extends Notifier<int> {
  @override
  int build() {
    ref.watch(batchSizeProvider);
    return 0;
  }
}

rrousselGit avatar Dec 14 '24 17:12 rrousselGit

I did try with ref.listen instead of ref.watch because I might want to call some other function instead of just resetting.

But I think ProgressNotifier is lazy build so the listen happens only if it has been evaluated first.

Can we force ProgressNotifier to build when batchSizeProvider is build so it can listen to it as soon as available ?

stephane-archer avatar Dec 14 '24 20:12 stephane-archer

ref.watch doesn't seem to work. It gets executed once, and then after that, the build is never called again when BatchSizeNotifier.state changes. Do you see any issues here? Screenshot 2024-12-15 at 02 12 42 Screenshot 2024-12-15 at 02 13 07

import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:zero_loss_compress/convertion_stats.dart';

final batchSizeProvider = NotifierProvider<BatchSizeNotifier, int>(() {
  return BatchSizeNotifier();
});

final progressProvider = NotifierProvider<ProgressNotifier, int>(() {
  return ProgressNotifier();
});

class BatchSizeNotifier extends Notifier<int> {
  @override
  int build() {
    return 0;
  }

  void setBatchSizeAndResetConversionState(int batchSize) {
    state = batchSize;
    //ref.read(progressProvider.notifier).reset();
    ref.read(convertionStatsStateProvider.notifier).reset();
  }
}

class ProgressNotifier extends Notifier<int> {
  @override
  int build() {
    ref.watch(batchSizeProvider);
    return 0;
  }

  void increment() {
    state = state + 1;
  }

  void reset() {
    state = 0;
  }
}

stephane-archer avatar Dec 15 '24 01:12 stephane-archer

Let me guess: Your UI never listens to progressProvider

Providers rebuild only if they are in use.

rrousselGit avatar Dec 15 '24 03:12 rrousselGit

@rrousselGit if I call BatchSizeNotifier.setBatchSizeAndResetConversionState(16) the listen/watch works. Then, if I call BatchSizeNotifier.setBatchSizeAndResetConversionState(16) again, it doesn't work because state == 16. Is there any way to listen for state assignments rather than value change?

stephane-archer avatar Dec 15 '24 12:12 stephane-archer

@rrousselGit also, if a provider listen to another provider and the info it carries is not shown on the screen, I don't think it's safe to assume that the provider no longer needed. showing it's value in a later stage would result in a wrong value.

Let's imagine a provider that tracks how many times another provider changed and displays it on another screen. if you don't listen when you are not displayed, how are things supposed to work here?

stephane-archer avatar Dec 15 '24 12:12 stephane-archer