Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent "Tried to use Provider with a subtype of Listenable/Stream" flutter error

I want to use the provider package(4.0) in my flutter project but i get the "Tried to use Provider with a subtype of Listenable/Stream" error/warning.

My constelation:

I have an Api() class which contains base CRUD functionality for firebase-cloudstorage.

I have an EventService()-class which uses the Api()-class with a concrete parameter.

For my view i have a ViewModel class called EventOverviewModel which uses the EventService.

My provider configuration looks like this:

List<SingleChildWidget> providers = [
  ...independentServices,
  ...dependentServices,
  ...uiConsumableProviders,
];

// Services die unabhängig von anderen sind
List<SingleChildWidget> independentServices = [
  Provider<EventService>(create: (_) => EventService(api: Api('events')))
];

// Services die von anderen Services abhängig sind
List<SingleChildWidget> dependentServices = [
  ProxyProvider<EventService, EventOverviewModel>(
    update: (_, srvc, __) => EventOverviewModel(eventService: srvc),
  )
];

List<SingleChildWidget> uiConsumableProviders = [];

Everything seems to work in the application but i get the "Tried to use Provider with a subtype of Listenable/Stream" anyway.

How should i change my code to not getting this error message anymore?

Running Gradle task 'assembleDebug'...
I/flutter (16553): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (16553): The following assertion was thrown building NumericProxyProvider<EventService, Void, Void, Void,
I/flutter (16553): Void, Void, EventOverviewModel>(dirty, dependencies: [InheritedProvider<EventService>], state:
I/flutter (16553): _ProxyProviderState<EventOverviewModel>#8d38d):
I/flutter (16553): Tried to use Provider with a subtype of Listenable/Stream (EventOverviewModel).
I/flutter (16553): 
I/flutter (16553): This is likely a mistake, as Provider will not automatically update dependents
I/flutter (16553): when EventOverviewModel is updated. Instead, consider changing Provider for more specific
I/flutter (16553): implementation that handles the update mechanism, such as:
I/flutter (16553): 
I/flutter (16553): - ListenableProvider
I/flutter (16553): - ChangeNotifierProvider
I/flutter (16553): - ValueListenableProvider
I/flutter (16553): - StreamProvider
I/flutter (16553): 
I/flutter (16553): Alternatively, if you are making your own provider, consider using InheritedProvider.
I/flutter (16553): 
I/flutter (16553): If you think that this is not an error, you can disable this check by setting
I/flutter (16553): Provider.debugCheckInvalidValueType to `null` in your main file:
I/flutter (16553): 
I/flutter (16553): ```
I/flutter (16553): void main() {
I/flutter (16553):   Provider.debugCheckInvalidValueType = null;
I/flutter (16553): 
I/flutter (16553):   runApp(MyApp());
I/flutter (16553): }
I/flutter (16553): ```
I/flutter (16553): 
I/flutter (16553): 
I/flutter (16553): The relevant error-causing widget was:
I/flutter (16553):   NumericProxyProvider<EventService, Void, Void, Void, Void, Void, EventOverviewModel>
I/flutter (16553):   file:///E:/Dev/flutter/.pub-cache/hosted/pub.dartlang.org/provider-3.2.0/lib/src/proxy_provider.dart:232:12
I/flutter (16553): 
I/flutter (16553): When the exception was thrown, this was the stack:
I/flutter (16553): #0      Provider.debugCheckInvalidValueType.<anonymous closure>.<anonymous ...
like image 986
rubiktubik Avatar asked Dec 28 '19 17:12

rubiktubik


2 Answers

Try changing

List<SingleChildWidget> independentServices = [
  Provider<EventService>(create: (_) => EventService(api: Api('events')))
];

to:

List<SingleChildWidget> independentServices = [
  ListenableProvider<EventService>(create: (_) => EventService(api: Api('events')))
];

And

List<SingleChildWidget> dependentServices = [
  ProxyProvider<EventService, EventOverviewModel>(
    update: (_, srvc, __) => EventOverviewModel(eventService: srvc),
  )
];

to:

List<SingleChildWidget> dependentServices = [
  ListenableProxyProvider<EventService, EventOverviewModel>(
    update: (_, srvc, __) => EventOverviewModel(eventService: srvc),
  )
];

I'm guessing EventService or EventOverviewModel extend or mixin ChangeNotifier and somewhere in your code you are listening for changes in values of Provider<EventService> and ProxyProvider<EventOverviewModel>, but those changes will never be broadcast/received unless your providers are "Listenable".

So if your models extend/mixin ChangeNotifier, and they are calling notifyListeners(), providers of those models need to be at least "Listenable".

ListenableProvider
ListenableProxyProvider

... or better yet, your models could use ChangeNotifier versions:

ChangeNotifierProvider
ChangeNotifierProxyProvider

... which conveniently disposes / detaches any listeners (frees up resources) when these objects are no longer in use.

like image 131
Baker Avatar answered Oct 31 '22 00:10

Baker


When using the Provider package, there are a few issues. All provider instances declared in the in the providers:[] are not listenable by default. As such you need to initialize them as such by using either ChangeNotifierProvider(create: (_) =>Model()) or ListenableProvider(create: (_) =>Model()) or StreamProvider(create: (_) =>Model()) in this case

    List<SingleChildWidget> independentServices = [
  ChangeNotifierProvider<EventService>(create: (_) => EventService(api: Api('events')))
];

// Services die von anderen Services abhängig sind
List<SingleChildWidget> dependentServices = [
  ChangeNotifierProxyProvider<EventService, EventOverviewModel>(
    update: (_, srvc, __) => EventOverviewModel(eventService: srvc),
  )
];
like image 3
O'neya Avatar answered Oct 31 '22 01:10

O'neya