I'm trying to provide a Bloc to my app that is dependant on another service. Inside that Bloc I'm listening to streams from the injected service. It's throwing this error:
Tried to use Provider with a subtype of Listenable/Stream (UserBloc).
- ListenableProvider
- ChangeNotifierProvider
- ValueListenableProvider
- StreamProvider
Alternatively, if you are making your own provider, consider using InheritedProvider.
...
This is the code for my providers, there's more, but these are causing problems:
MultiProvider(
providers: [
Provider<AuthService>(create: authServiceBuilder),
ProxyProvider<AuthService, DatabaseService>(
update: (_, authService, __) => databaseBuilder(_, authService),
),
ProxyProvider<DatabaseService, UserBloc>(
create: (_) => UserBloc(),
update: (_, database, bloc) => bloc..updateDependencies(database),
dispose: (_, bloc) => bloc.close(),
),
ProxyProvider<UserBloc, ProfileBloc>(
create: (_) => ProfileBloc(),
update: (_, userBloc, bloc) => bloc..updateDependencies(userBloc),
dispose: (_, bloc) => bloc.close(),
),
]
)
The Blocs are throwing the errors, other services work fine.
I tried creating the Blocs in the update parameter of the ProxyProvider, similar to the DatabaseService ProxyProvider above but that doesn't work.
I then made it so that I'm creating the Blocs in the create parameter, and when update is called, I unsubscribe from any streams and resubscribe, and then call the Blocs close() method on dispose. But it's showing the same error.
This is roughly what my UserBloc looks like:
class UserBloc extends Bloc<UserEvent, UserState> {
DatabaseService _database;
/// The UI will always reflect this local cache.
final _userCache = BehaviorSubject<User>();
StreamSubscription<User> _userSub;
StreamSubscription<User> _userCacheSub;
UserBloc() {
// When the cache updates, update the UI immediately.
_userCacheSub = _userCache.listen((user) => add(UserUpdated(user)));
}
void updateDependencies(DatabaseService database) {
// Store a new reference to the database.
_database = database;
// Cancel existing subscriptions
if (_userSub != null) _userSub.cancel();
// Database is always the source of truth. Push upates straight to the cache
_userSub = _database.userStream.listen((user) => _userCache.add(user));
}
@override
Future<void> close() {
_userSub.cancel();
_userCacheSub.cancel();
return super.close();
}
}
Whats the best way to have Bloc to Bloc dependency? Do I have to have them under a consumer and provide it below or is there a way to have it working with ProxyProvider?