Skip to main content

Live Queries

Description — Couchbase Lite Live Query Concepts
Related Content — SQL++ for Mobile | QueryBuilder

Activating a Live Query

A live query is a query that, once activated, remains active and monitors the database for changes; refreshing the result set whenever a change occurs. As such, it is a great way to build reactive user interfaces — especially table/list views — that keep themselves up to date.

So, a simple use case may be: A replicator running and pulling new data from a server, whilst a live-query-driven UI automatically updates to show the data without the user having to manually refresh. This helps your app feel quick and responsive.

With Couchbase Lite for Dart, live queries can be watched through:

Each time you start watching a live query, the query is executed and an initial change notification is dispatched. The query is then kept active and further change notifications are dispatched whenever a change occurs.

Watching with Change Listeners

In the case of the synchronous API, all changes are delivered to the listeners as soon as they are registered.

With the asynchronous API, changes are only guaranteed to be delivered once the Future returned from the registration call is completed:

Example 1. Starting a Live Query - Change Listener
// Await the future returned from the registration call.
await query.addChangeListener((change) async {
final results = await change.results.allResults();
for (final result in results) {
// Do something with the result...

To stop receiving notifications, call Query.removeChangeListener with the token that was returned from the registration call. Regardless of the whether the API is synchronous or asynchronous, listeners will stop receiving notifications immediately:

Example 2. Stopping a Live Query - Change Listener
final token = await query.addChangeListener((change) async { ... });

// Some time goes by...

await query.removeChangeListener(token);

Watching with Streams

Streams are a convenient alternative to listen for changes. Similarly to change listeners, change streams returned from the synchronous API are receiving changes as soon as the stream is subscribed to.

Streams returned from the asynchronous API start to listen asynchronously. Unfortunately it's not possible to return a Future from Stream.listen to signal to subscribers the point in time after which the the stream will observe events. Instead, the asynchronous API returns a AsyncListenStreams, which expose a Future in AsyncListenStream.listening that completes when the stream is fully listening:

Example 3. Starting a Live Query - Stream
final stream = query.changes();

stream.listen((change) async {
final results = await change.results.allResults();
for (final result in results) {
// Do something with the result...

// Await the Future exposed by the stream.
await stream.listening;

To stop listening to changes just cancel the subscription, like with any other stream.