Search code examples
angularsignalsrxdb

NG0602 when using RxDB reactivity factory


My use case: Use a reactive rxDB.collection.find().$$() inside a computed angular signal. I am quite sure I am misreading the current documentation :/

Reading the current RxDB documentation I can see that I can make RxDB provide Angular Signals via the reactivityFactory (awesome!!!). If I follow the documentation I end up with an NG0602 error since we cannot create signals within a reactive context. See: https://stackblitz.com/edit/rxdb-15-angular-17-playground-azqzjo?file=src%2Fapp%2Fapp.component.ts

The issue comes from the fact, that

protected cars = computed(() => {
    if (this.isLoading()) return [];
    return this.db.cars.find().$$();
  });

internally calls the reactivityFactory.

If I work around this issue e.g. by using the toLazySignal util from ngxtension it creates a signal everytime a collection change happens, see https://stackblitz.com/edit/rxdb-15-angular-17-playground-1ky4q9?file=src%2Fapp%2Fapp.component.ts (open the browser console)

How should I implement the reactivityFactory corretly so that my use case works?


Solution

  • Solved! The issue was a total different one. The observable actually returned an error, which was swallowed by toSignal.

    The error:

    Error (QU13): RxError (QU13):
    A top level field of the query is not included in the schema
    Given parameters: {
    schema:{
      "additionalProperties": false,
      "encrypted": [],
      "indexes": [
    ...
    

    That was the reason why the signal got create again immediately which created an endless loop that ended in a browser crash. Adding rejectErrors: true to the toSignal options helped a lot.

    So the reactivity factory should be something like this:

    export function createReactivityFactory(injector: Injector): RxReactivityFactory<Signal<any>> {
      return {
        fromObservable(observable$, initialValue: any) {
          return untracked(() =>
            toSignal(observable$, {
              initialValue,
              injector,
              rejectErrors: true
            })
          );
        }
      };
    }
    

    Edit: The updated documentation: https://rxdb.info/reactivity.html#adding-a-custom-reactivity-factory-in-angular-projects