Flutter Bloc with ProxyProvider error: Tried to use Provider with a subtype of Listenable/Stream

Viewed 916

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?

0 Answers
Related