watch method

Stream<Query<T>> watch({
  1. bool triggerImmediately = false,
})

Builds the Query and creates a single-subscription Stream that sends the query whenever there are changes to the boxes of the queried entities.

Use triggerImmediately to send an event immediately after subscribing, even before an actual change.

A common use case is to get a list of the latest results for a UI widget:

// Map to a stream of results, immediately get current results.
final Stream<List<Entity>> listStream = box.query()
    .watch(triggerImmediately: true)
    .map((query) => query.find());

However, this method allows to do whatever needed with the returned query:

box.query().watch().listen((query) {
  // Do something with query, e.g. find or count.
});

The stream is a single-subscription stream, so can only be listened to once. The query returned by the stream is persisted between events and can be used even after the subscription is cancelled (the query is not explicitly closed).

Implementation

Stream<Query<T>> watch({bool triggerImmediately = false}) {
  final queriedEntities = HashSet<Type>();
  _fillQueriedEntities(queriedEntities);
  final query = build();
  late StreamSubscription<void> subscription;
  late StreamController<Query<T>> controller;

  subscribe() {
    subscription = _store.entityChanges.listen((List<Type> entityTypes) {
      if (entityTypes.any(queriedEntities.contains)) {
        controller.add(query);
      }
    });
  }

  // Note: this can not be a broadcast StreamController (to allow
  // re-subscribing or multiple subscribers) as it would not be
  // possible to implement the send on listen (triggerImmediately)
  // functionality (onListen is only called for the first subscriber,
  // also does not allow to send an event within).
  controller = StreamController<Query<T>>(
      onListen: subscribe,
      onResume: subscribe,
      onPause: () => subscription.pause(),
      onCancel: () => subscription.cancel());
  if (triggerImmediately) controller.add(query);
  return controller.stream;
}