{"id":13808797,"url":"https://github.com/voznik/ngx-odm","last_synced_at":"2026-01-18T12:26:50.060Z","repository":{"id":46671027,"uuid":"174150280","full_name":"voznik/ngx-odm","owner":"voznik","description":"Angular 14+ wrapper for RxDB","archived":false,"fork":false,"pushed_at":"2024-04-12T04:57:21.000Z","size":5366,"stargazers_count":37,"open_issues_count":4,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-15T07:23:35.635Z","etag":null,"topics":["angular","kinto","library","nosql","pouchdb","replication","rxdb","rxjs","streamlit-component","typescript"],"latest_commit_sha":null,"homepage":"https://voznik.github.io/ngx-odm","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/voznik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-06T13:27:20.000Z","updated_at":"2024-05-02T15:42:54.832Z","dependencies_parsed_at":"2024-02-10T11:31:31.585Z","dependency_job_id":"72c7943a-b184-434b-b7f8-8619b323a1ec","html_url":"https://github.com/voznik/ngx-odm","commit_stats":{"total_commits":50,"total_committers":3,"mean_commits":"16.666666666666668","dds":0.4,"last_synced_commit":"f7e3031d2936fa3a88df5b807a21857c05555a4b"},"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voznik%2Fngx-odm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voznik%2Fngx-odm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voznik%2Fngx-odm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voznik%2Fngx-odm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voznik","download_url":"https://codeload.github.com/voznik/ngx-odm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247645399,"owners_count":20972471,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["angular","kinto","library","nosql","pouchdb","replication","rxdb","rxjs","streamlit-component","typescript"],"created_at":"2024-08-04T01:01:52.242Z","updated_at":"2025-04-10T11:26:23.445Z","avatar_url":"https://github.com/voznik.png","language":"TypeScript","funding_links":[],"categories":["Table of contents"],"sub_categories":["Third Party Components"],"readme":"# @ngx-odm/rxdb\n\n\u003e Angular 14+ wrapper for **RxDB** - A realtime Database for the Web\n\n## Demo\n\n![Example Screencast](examples/screencast.gif)\n\n[demo](https://voznik.github.io/ngx-odm/) - based on TodoMVC\n\n## Table of contents\n\n- [@ngx-odm/rxdb](#ngx-odmrxdb)\n  - [Demo](#demo)\n  - [Table of contents](#table-of-contents)\n  - [General info](#general-info)\n  - [Technologies](#technologies)\n  - [Install](#install)\n  - [Usage (NgModule)](#usage-ngmodule)\n    - [In your `AppModule`](#in-your-appmodule)\n    - [In your `FeatureModule`](#in-your-featuremodule)\n    - [In your `FeatureService`](#in-your-featureservice)\n  - [Usage (Standalone)](#usage-standalone)\n    - [In your `main.ts`](#in-your-maints)\n    - [In your `Component`](#in-your-component)\n    - [Using `sginals` \\\u0026 `signalStore` from `@ngrx/signals`](#using-sginals--signalstore-from-ngrxsignals)\n  - [Features](#features)\n  - [Status](#status)\n  - [Inspiration](#inspiration)\n  - [Notes](#notes)\n  - [Contact](#contact)\n\n## General info\n\nIf you don't want to setup RxDB manually in your next Angular project - just import `NgxRxdbModule` or go with `provideRxDatabase` and `provideRxCollection` if standalone component is your choice.\n\n## Technologies\n\n| RxDB                                                                                                     | Angular 14+                                                                                   |\n| -------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |\n| [![RxDB](https://cdn.rawgit.com/pubkey/rxdb/ba7c9b80/docs/files/logo/logo_text.svg)](https://rxdb.info/) | [![Angular](https://angular.io/assets/images/logos/angular/angular.svg)](https://angular.io/) |\n\n## Install\n\n`npm install @ngx-odm/rxdb`\n\n## Usage (NgModule)\n\n### In your `AppModule`\n\n```typescript\nimport { NgxRxdbModule } from '@ngx-odm/rxdb';\nimport { getRxDatabaseCreator } from '@ngx-odm/rxdb/config';\n\n@NgModule({\n  imports: [\n    // ... other imports\n    NgxRxdbModule.forRoot(\n      getRxDatabaseCreator({\n        name: 'demo', // \u003c- name (required, 'ngx')\n        storage: getRxStorageDexie(), // \u003c- storage (not required, 'dexie')\n        localDocuments: true,\n        multiInstance: true, // \u003c- multiInstance (optional, default: true)\n        ignoreDuplicate: false,\n        options: {\n          plugins: [\n            // will be loaded by together with core plugins\n            RxDBDevModePlugin, // \u003c- add only for development\n            RxDBAttachmentsPlugin,\n            RxDBLeaderElectionPlugin,\n          ],\n          storageType: 'dexie|memory', // \u003c- storageType (optional, use if you want defaults provided automatically)\n          dumpPath: 'assets/dump.json', // path to datbase dump file (optional)\n        },\n      })\n    ),\n  ],\n  providers: [],\n  bootstrap: [AppComponent],\n})\nexport class AppModule {}\n```\n\n### In your `FeatureModule`\n\n\u003e Schemas define how your data looks. Which field should be used as primary, which fields should be used as indexes and what should be encrypted. The schema also validates that every inserted document of your collections conforms to the schema. Every collection has its own schema. With RxDB, schemas are defined with the jsonschema-standard which you might know from other projects.\n\u003e https://rxdb.info/rx-schema.html\n\n```typescript\nimport type { RxCollectionCreatorExtended } from '@ngx-odm/rxdb/config';\n// create or import your schema\nconst todoSchema: RxSchema = require('../../../assets/data/todo.schema.json');\n// create config\nconst todoCollectionConfig: RxCollectionCreatorExtended = {\n  name: 'todo', // \u003c- name (required)\n  schema: todoSchema, // \u003c- schema (not required, see below)\n  localDocuments: true,\n  options: {\n    initialDocs: [], // docs to be imported into empty collection (optional)\n    schemaUrl: 'assets/data/todo.schema.json', // load schema from remote url (optional)\n    replicationStateFactory: collection =\u003e {\n      // provide replication state (optional)\n    },\n  },\n};\n\n@NgModule({\n  imports: [\n    // ... other imports\n    NgxRxdbModule.forFeature(todoCollectionConfig),\n  ],\n})\nexport class TodosModule {\n  constructor(\n    @Inject(RXDB_COLLECTION) private collectionService: RxDBCollectionService\u003cTodo\u003e\n  ) {\n    this.collectionService.sync(); // INFO: collection is ready\n  }\n}\n```\n\n### In your `FeatureService`\n\n```typescript\nimport { RXDB_COLLECTION } from '@ngx-odm/rxdb';\nimport { RxDBCollectionService } from '@ngx-odm/rxdb/collection';\n\n@Injectable()\nexport class TodosService {\n  private collectionService: RxDBCollectionService\u003cTodo\u003e =\n    inject\u003cRxDBCollectionService\u003cTodo\u003e\u003e(RXDB_COLLECTION);\n  // store \u0026 get filter as property of a `local` document\n  filter$ = this.collectionService\n    .getLocal('local', 'filterValue')\n    .pipe(startWith('ALL'), distinctUntilChanged());\n  // get count of documents in collection as observable\n  count$ = this.collectionService.count();\n\n  // get documents from collection as observable\n  // optionally using `RxQuery` mango-queries\n  todos$: Observable\u003cTodo[]\u003e = this.collectionService.docs();\n\n  // add new document\n  add(name: string): void {\n    const payload: Todo = { guid: uuid(), name, done: false, dateCreated: Date.now() };\n    this.collectionService.insert(payload);\n  }\n\n  // update property of single document\n  toggle(guid: string, done: boolean): void {\n    this.collectionService.set(guid, { done });\n  }\n\n  // update many documents with partial data by query\n  toggleAllTodos(completed: boolean) {\n    this.collectionService.updateBulk(\n      { selector: { completed: { $eq: !completed } } },\n      { completed }\n    );\n  }\n\n  // remove many dcouments by qeury\n  removeCompletedTodos(): void {\n    this.collectionService.removeBulk({ selector: { completed: true } });\n  }\n  // ...\n}\n```\n\n## Usage (Standalone)\n\n### In your `main.ts`\n\n```typescript\nimport { provideRxDatabase } from '@ngx-odm/rxdb';\nimport { getRxDatabaseCreator } from '@ngx-odm/rxdb/config';\n\nexport const appConfig: ApplicationConfig = {\n  providers: [\n    // ... other providers\n    provideRxDatabase(\n      getRxDatabaseCreator({\n        name: 'demo',\n        localDocuments: true,\n        multiInstance: true,\n        ignoreDuplicate: false,\n        storage: getRxStorageDexie(),\n        plugins: [\n          // will be loaded by together with core plugins\n          RxDBDevModePlugin, // \u003c- add only for development\n          RxDBAttachmentsPlugin,\n          RxDBLeaderElectionPlugin,\n        ],\n      })\n    ),\n  ],\n};\n\nbootstrapApplication(AppComponent, appConfig).catch(err =\u003e console.error(err));\n```\n\n### In your `Component`\n\n```typescript\nimport { provideRxCollection } from '@ngx-odm/rxdb';\n\n@Component({\n  standalone: true,\n  // ...\n  providers: [provideRxCollection(config)],\n})\nexport class StandaloneComponent {\n  readonly todoCollection = inject(NgxRxdbCollectionService\u003cTodo\u003e);\n}\n```\n\n### Using `sginals` \u0026 `signalStore` from `@ngrx/signals`\n\n```typescript\nimport { signalStore } from '@ngrx/signals';\nimport { withEntities } from '@ngrx/signals/entities';\nimport { withCollectionService } from '@ngx-odm/rxdb/signals';\nimport { withDevtools } from '@angular-architects/ngrx-toolkit';\n\nexport const TodoStore = signalStore(\n  { providedIn: 'root' },\n  withDevtools('todo'),\n  withEntities\u003cTodo\u003e(),\n  // INFO: an instance of RxCollection will be provided by this\n  withCollectionService\u003cTodo, TodosFilter, RxCollectionCreatorExtended\u003e({\n    filter: 'ALL' as TodosFilter,\n    collectionConfig: TodosCollectionConfig,\n  }),\n  ...\n);\n\n@Component({\n  standalone: true,\n  // ...\n  providers: [TodoStore],\n})\nexport class StandaloneComponent {\n  readonly todoStore = inject(TodoStore);\n\n  constructor() {\n    effect(() =\u003e {\n      const { filter, entities } = this.todoStore;\n    });\n  }\n}\n```\n\n## Features\n\nBy using this module you can simplify your work with RxDB in Angular application:\n\n- Automatically initialize db with settings\n  - optionally provide db dumb to pre-fill collections\n  - optionally provide array of initial documents to pre-fill collection\n  - optionally provide remote location for schema and fetch it automatically before create collection (e.g. to maintain single source of truth for schema)\n  - optionally provide syncronization with remote db (CouchDB, Kinto etc.) as DB options\n- Automatically initialize RxCollection for each _lazy-loaded Feature module / standalone component_ with config\n- Work with documents via _NgxRxdbCollectionService_ with unified methods instead of using _RxCollection_ directly (though you still have access to _RxCollection_ and _RxDatabase_ instance)\n  - simple methods to work database \u0026 documents (with queries)\n  - simple methods to work with local documents\n  - simple methods to work with attachments\n  - simple replication sync initialization\n- Work with signals and entities with `@ngrx/signals` and `@ngrx/entity` (optionally _zoneless_) (see [example](examples/standalone/src/app/todos/todos.store.ts))\n- Persist collection query ([mango-query-syntax](https://github.com/cloudant/mango)) in URL with new plugin `query-params-plugin` (in demo, set localStorage `_ngx_rxdb_queryparams` )\n  - provide Observable of current URL (automatically for Angular)\n  - simple methods to set or patch filter, sort, limit, skip\n\n\u003c!-- ## Diagrams\n\n![NgxRxdbModule Initialization UML](examples/uml.NgxRxdbModule.png)\nNgxRxdbModule Initialization UML\n\n![NgxRxdbService Sequence UML](examples/uml.NgxRxdbService.png)\nNgxRxdbModule Initialization UML --\u003e\n\n## Status\n\nProject is: _in progress_\n\n## Inspiration\n\nProject inspired by\n\n- [rxdb-angular2-example](https://github.com/pubkey/rxdb/blob/master/examples/angular2/README.md#rxdb-angular2-example)\n- [Angular NgRx Material Starter](https://tomastrajan.github.io/angular-ngrx-material-starter#/examples/todos)\n- _The Angular Library Series_ from [Angular In Depth](https://blog.angularindepth.com/)\n- [NgRx Toolkit](https://github.com/angular-architects/ngrx-toolkit/blob/main/libs/ngrx-toolkit/src/lib/with-data-service.ts) - inspired by Manfred Steyer and created singnals tool by analogy of `withDataService` from [Angular Architects](https://angulararchitects.io/)\n\n## Notes\n\n## Contact\n\nCreated by [@voznik](https://github.com/voznik) - feel free to contact me!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoznik%2Fngx-odm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoznik%2Fngx-odm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoznik%2Fngx-odm/lists"}