2

I'm trying to inject instances of services (that have been created in the same tree level) into another provider. But down the tree when accessing the provider, I get ProviderNotFoundException exception. In the following code NotificationService depends on AuthService. Which needs to be passed in the constructor. Hence I inject it using Consumer and Provider.value as mentioned in the docs: https://pub.dev/documentation/provider/latest/provider/Consumer-class.html

Here is the pseudo-code:

return MultiProvider(
    providers: [
      Provider<AuthService>(
        create: (ctx) => AuthService(_storage),
        dispose: (ctx, v) => v.dispose(),
      ),
      Consumer<AuthService>(
        builder: (context, v, child) {
          return Provider.value(
              value: Provider<NotificationService>(
                create: (ctx) => NotificationService(v),
                dispose: (ctx, v) => v.dispose(),
              ),
              child: child
          );
        },
      )
    ],
    child: MyApp()
);

Somewhere down the tree line, When trying to access the NotificationService instance, I get ProviderNotFoundException:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final NotificationService _ns = Provider.of<NotificationService>(context);
  }
}

Error:

I/flutter ( 4614): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 4614): The following ProviderNotFoundException was thrown building MyApp(dirty, dependencies:
I/flutter ( 4614): [_DefaultInheritedProviderScope<AuthService>]):
I/flutter ( 4614): Error: Could not find the correct Provider<NotificationService> above this MyApp Widget
I/flutter ( 4614): 
I/flutter ( 4614): To fix, please:
I/flutter ( 4614): 
I/flutter ( 4614):   * Ensure the Provider<NotificationService> is an ancestor to this MyApp Widget
I/flutter ( 4614):   * Provide types to Provider<NotificationService>
I/flutter ( 4614):   * Provide types to Consumer<NotificationService>
I/flutter ( 4614):   * Provide types to Provider.of<NotificationService>()
I/flutter ( 4614):   * Ensure the correct `context` is being used.
I/flutter ( 4614): 

I don't fully understand this, and I'm pretty sure there is a mistake in the above code. What am I doing wrong?

dora
  • 1,314
  • 2
  • 22
  • 38

1 Answers1

12

The way you used Provider.value is invalid. But you don't actually need Consumer+Provider. You can do:

MultiProvider(
  providers: [
    Provider(create: (_) => A()),
    Provider(create: (context) => B(Provider.of<A>(context, listen: false)),
  ],
)
om-ha
  • 3,102
  • 24
  • 37
Rémi Rousselet
  • 256,336
  • 79
  • 519
  • 432
  • Thank you. This solved it. I went through the api docs: https://pub.dev/documentation/provider/latest/provider/Provider/of.html. But I couldn't really make sense of the explanation, what does `listen: false` do exactly? – dora Feb 24 '20 at 15:59
  • 1
    @dora check out my [answer here](https://stackoverflow.com/a/59900307/10830091) to better understand the listen flag. It refers to the docs as well. – om-ha Feb 25 '20 at 07:52
  • @Rémi In the case of wanting to update `Provider` `B` when `Provider` `A` is updated, then we'd need to use a `ProxyProvider` for `B`. Correct me if I'm wrong. – om-ha Feb 25 '20 at 07:56