1

I have a provider named gameControllerProvider extends with ChangeNotifier, I initialize it first throw UnimplementedError.

final gameControllerProvider =
ChangeNotifierProvider<GameController>((ref) => throw UnimplementedError());

In my GameBodyWidget I ovverridewith value my gameControlllerProvider

class GameBodyWidget extends ConsumerWidget {
  /// {@macro game_body_screen}
  const GameBodyWidget({Key? key, required this.gameLevel}) : super(key: key);

  final GameLevel gameLevel;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return ProviderScope(
      overrides: [
        gameControllerProvider.overrideWithValue(
          GameController()..initializeController(gameLevel, ref),
        ),
      ],
      child: Stack(
        ...
      ),
    );
  }

As you can see, the reason why I override the controller provider because I need to initialize and pass the parameter of WidgetRef and the GameLevel instance. Yeah I know I can use the .family method but the problem there is that when I need to call this provider I always pass the parameter

ref.watch(gameControllerProvider('exampleParameter'));

2 Answers2

4

As the changelog says, overrideWithValue is temporarily removed.
But to begin with, in the code you shared, you shouldn't be using it.

Instead do:

ProviderScope(
  overrides: [
    gameControllerProvider.overrideWithProvider(
      ChangeNotifierProvider((ref) {
        return GameController()..initializeController(gameLevel, ref),
      }),
    ),
  ],
)

Using overrideWithValue here is unsafe as a ChangeNotifier is a stateful object. If the widget somehow rebuilt, your ChangeNotifier would be recreated and your state would be lost.

Using overrideWithProvider does not have this issue, as the provider will cache the ChangeNotifier.

Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
1

For now you can use overrideWithProvider.

This change is temporary, and these methods will be reintroduced in a later version.

Ruble
  • 2,589
  • 3
  • 6
  • 29