Skip to main content

Signals & Co. - Custom reactivity adapters instead of RxJS Observables

RxDB internally uses the rxjs library for observables and streams. All functionalities of RxDB like query results or document fields that expose values that change over time return a rxjs Observable that allows you to observe the values and update your UI accordingly depending on the changes to the database state.

However there are many reasons to use other reactivity libraries that use a different datatype to represent changing values. For example when you use signals in angular or react, the template refs of vue or state libraries like MobX and redux.

RxDB allows you to pass a custom reactivity factory on RxDatabase creation so that you can easily access values wrapped with your custom datatype in a convenient way.

Adding a custom reactivity factory

So get custom reactivity objects out of RxDB, you have to pass a RxReactivityFactory during database creation. The RxReactivityFactory has the fromObservable() method that creates your custom reacitvity object based on an observable and an initial value.

For example to use signals in angular, you can use the angular toSignal function:

import { RxReactivityFactory } from 'rxdb/plugins/core';
import { toSignal } from '@angular/core/rxjs-interop';
const reactivityFactory: RxReactivityFactory<ReactivityType> = {
fromObservable(obs, initialValue) {
return toSignal(obs, { initialValue });
}
};

Then you can pass this factory when you create the RxDatabase:

import { createRxDatabase } from 'rxdb/plugins/core';
const database = await createRxDatabase({
name: 'mydb',
storage: getRxStorageDexie(),
reactivity: reactivityFactory
});

Accessing custom reactivity objects

All observable data in RxDB is marked by the single dollar sign $ like RxCollection.$ for events or RxDocument.myField$ to get the observable for a document field. To make custom reactivity objects distinguable, they are marked with double-dollar signs $$ instead. Here are some example on how to get custom reactivity objects from RxDB specific instances:

// RxDocument
const signal = myRxDocument.get$$('foobar'); // get signal that represents the document field 'foobar'
const signal = myRxDocument.foobar$$; // same as above
const signal = myRxDocument.$$; // get signal that represents whole document over time
const signal = myRxDocument.deleted$$; // get signal that represents the deleted state of the document
// RxQuery
const signal = collection.find().$$; // get signal that represents the query result set over time
const signal = collection.findOne().$$; // get signal that represents the query result set over time

Limitations

  • Custom reactivity is in beta mode, it might have breaking changes without a major RxDB release.
  • TypeScript typings are not fully implemented, make a PR if something is missing or not working for you.
  • Currently not all observables things in RxDB are implemented to work with custom reactivity. Please make a PR if you have the need for any missing one.