user9661910
user9661910

Reputation: 74

Flutter: Disposing of resources in @riverpod generated provider

I am using riverpod_generator in my Flutter app to generate a provider for a controller that I use. The controller is actually a Notifier.

I am wondering where is the correct place in the controller to set up the disposal of resources (in this case, a BehaviorSubject, and its stream's subscription.

Is it ok to do it in the build() method, as I have in the included code? Thanks

part "provider.g.dart";

final PlayersSearchFiltersValue _initialFilters = PlayersSearchFiltersValue(
  searchTerm: "",
);

@riverpod
class PlayersSearchAppController extends _$PlayersSearchAppController
    implements PlayersSearchController {
  late final PlayersService playersService =
      ref.read(playersAppServiceProvider);

  final BehaviorSubject<PlayersSearchFiltersValue> _filtersSubject =
      BehaviorSubject();
  late StreamSubscription<PlayersSearchFiltersValue> _filtersSubscription;
  StreamSink<PlayersSearchFiltersValue> get _filtersSink =>
      _filtersSubject.sink;

  @override
  AsyncValue<List<PlayerModel>> build() {
    _initializeController();
    return AsyncValue.data([]);
  }

  /// rest of the code

  void _initializeController() {
    _filtersSubscription = _filtersSubject.stream
        .debounceTime(Duration(milliseconds: 500))
        .listen((event) {
      _onSearchPlayers(event);
    });

    ref.onDispose(() async {
      await _filtersSubscription.cancel();
      await _filtersSubject.close();
    });
  }
}

Upvotes: 3

Views: 2431

Answers (1)

Ruble
Ruble

Reputation: 4844

Yes, this will work great. The only thing, perhaps, is to define a separate _dispose method and allocate this piece of code to it in order to share responsibilities.


  @override
  AsyncValue<List<PlayerModel>> build() {
    _initializeController();
    _dispose();
    return AsyncValue.data([]);
  }

  void _dispose() {
    ref.onDispose(() async {
      await _filtersSubscription.cancel();
      await _filtersSubject.close();
    });
  }

  void _initializeController() {
    _filtersSubscription = _filtersSubject.stream
        .debounceTime(Duration(milliseconds: 500))
        .listen((event) {
      _onSearchPlayers(event);
    });
  }

Also, you should remember that generator by default creates providers that dispose their state (as with the dispose modifier). To change this behavior, use:

@Riverpod(keepAlive: true)

Upvotes: 2

Related Questions