Best practice for passing param Riverpod's providers only once

515 Views Asked by At

I just want to build a Provider which asks params only one and inits correctly.

  • Since I am just passing params only once, I don't prefer to use .family methods.

  • I prefer to use .autoDispose which considered the better way.

Here my tryouts:

  • I tried to make my own .init() method. But it's disposing as soon as method called if it's .autodispose() and the widget not started to listen my provider yet (that's expected). Therefore I couldn't consider a safe way to do that.

  • I tried .overrideWith() method in a widget basis. But it's neither worked nor I am sure that it's best practice.

Here is my simple code:

class MyHomePage extends ConsumerWidget {
  const MyHomePage({super.key});

  final myString = 'Hey';

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    //Not worked
    ProviderContainer(
        overrides: [messageProvider.overrideWith(() => ViewModel(myString))]);

    return Scaffold(
      body: ProviderScope(
        //Not worked either
        overrides: [messageProvider.overrideWith(() => ViewModel(myString))],
        child: Center(
          //I just didn't use .when to shorter code
          child: Text(ref.watch(messageProvider).value!.counter.toString()),
        ),
      ),
    );

  }
}
final messageProvider = AsyncNotifierProvider.autoDispose<ViewModel, Model>(
    () => throw UnimplementedError());

class ViewModel extends AutoDisposeAsyncNotifier<Model> {
  final String param;

  ViewModel(this.param);

  @override
  FutureOr<Model> build() {
    //Make some fetch with param, (only once!)
    return Model(param.length);
  }
}

When I run that. It gives UnimplementedError

Waiting your suggestions & fixes. Thanks in advance!

Expected: Works properly.

1

There are 1 best solutions below

0
On
@riverpod
ViewModel myViewModel(MyViewModelRef ref, String param){
    return ViewModel(param);
}

This is autoDispose by default in Riverpod 2. If you don't want to auto dispose you can use @Riverpod(keepalive:true) instead of @riverpod

If you don't want to pass the param to the provider, you can eliminate it and hardcode the value to the ViewModel, but at that point, if there are no other dependencies, might as well make it a public final variable in some file, since it looks like this is a singleton that never changes so it is questionable what you'd achieve by making it a Riverpod provider.