Skip to content

Dexie.js RxStorage: find() and findOne() with a selector always returns empty or null respectively #9061

Description

@mmgfrcs

Setup

My app is storing their data using RxDB using the Dexie.js storage adapter. The (reduced) setup is as follows:

import { getRxStorageDexie } from 'rxdb/plugins/storage-dexie';
import { addRxPlugin } from 'rxdb/plugins/core';
import { RxDBDevModePlugin } from 'rxdb/plugins/dev-mode';
import { wrappedValidateAjvStorage } from 'rxdb/plugins/validate-ajv';
import { createRxDatabase } from 'rxdb/plugins/core';
import { RxDBCleanupPlugin } from 'rxdb/plugins/cleanup';
import { RxDBLeaderElectionPlugin } from 'rxdb/plugins/leader-election'

let storage = wrappedValidateAjvStorage({ storage: getRxStorageDexie() });
addRxPlugin(RxDBDevModePlugin);
addRxPlugin(RxDBCleanupPlugin);
addRxPlugin(RxDBLeaderElectionPlugin);

const db = await createRxDatabase({
  name: 'assetTracker',
  storage: storage
});

await db.addCollections({
  // name of the collection
  assets: {
    localDocuments: true,
    // we use the JSON-schema standard
    schema: {
      version: 0,
      primaryKey: 'id',
      type: 'object',
      properties: {
        id: {
          type: 'string',
          maxLength: 100 // <- the primary key must have maxLength
        },
        value: {
          type: 'string',
        }
      },
      required: ['id', 'value']
    }
  }
});

Everything works well, I inserted some data as follows, and I can see them in the browser devtools

const assetMod = import.meta.glob<ImageMetadata>("/src/assets/**/*.webp", {import: "default"})

for(let assetPth in assetMod) {
    await db.assets.insert({id: assetPth, value: (await assetMod[assetPth]()).src})
}

Calling db.assets.find().exec() finds all of them successfully.

Problem

However, when I wanted to filter them with db.assets.findOne(iid).exec(), where iid is an id that exists, it returns null. Calling db.assets.find(iid).exec() also fails to return any results, resulting in an empty array ([])

Calling the following also returns null

  1. db.assets.findOne({selector: {id: iid}}).exec()
  2. db.assets.findOne({selector: {id: {$eq: iid}}}).exec()

And the same for the find version of the above, returning empty array.

Investigation

My bug-fixing session led me to a discovery. I tried to query a non-existent field it and it returns the raw query as follows:

query: {
  "selector": {
    "it": {
      "$eq": "101.webp"
    },
    "_deleted": {
      "$eq": false
    }
  },
  "limit": 1,
  "skip": 0,
  "sort": [
    {
      "_deleted": "asc"
    },
    {
      "id": "asc"
    }
  ]
}

find() and findOne() tries to find data that is not deleted, where _deleted = false, as the query states. However, in the db, _deleted is a string value of "0"

Image

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions