ProductPromotion
Logo

Angular.JS

made by https://0x3d.site

GitHub - voznik/ngx-odm: Angular 14+ wrapper for RxDB
Angular 14+ wrapper for RxDB. Contribute to voznik/ngx-odm development by creating an account on GitHub.
Visit Site

GitHub - voznik/ngx-odm: Angular 14+ wrapper for RxDB

GitHub - voznik/ngx-odm: Angular 14+ wrapper for RxDB

@ngx-odm/rxdb

Angular 14+ wrapper for RxDB - A realtime Database for the Web

Demo

Example Screencast

demo - based on TodoMVC

Table of contents

General info

If 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.

Technologies

RxDB Angular 14+
RxDB Angular

Install

npm install @ngx-odm/rxdb

Usage (NgModule)

In your AppModule

import { NgxRxdbModule } from '@ngx-odm/rxdb';
import { getRxDatabaseCreator } from '@ngx-odm/rxdb/config';

@NgModule({
  imports: [
    // ... other imports
    NgxRxdbModule.forRoot(
      getRxDatabaseCreator({
        name: 'demo', // <- name (required, 'ngx')
        storage: getRxStorageDexie(), // <- storage (not required, 'dexie')
        localDocuments: true,
        multiInstance: true, // <- multiInstance (optional, default: true)
        ignoreDuplicate: false,
        options: {
          plugins: [
            // will be loaded by together with core plugins
            RxDBDevModePlugin, // <- add only for development
            RxDBAttachmentsPlugin,
            RxDBLeaderElectionPlugin,
          ],
          storageType: 'dexie|memory', // <- storageType (optional, use if you want defaults provided automatically)
          dumpPath: 'assets/dump.json', // path to datbase dump file (optional)
        },
      })
    ),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

In your FeatureModule

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. https://rxdb.info/rx-schema.html

import type { RxCollectionCreatorExtended } from '@ngx-odm/rxdb/config';
// create or import your schema
const todoSchema: RxSchema = require('../../../assets/data/todo.schema.json');
// create config
const todoCollectionConfig: RxCollectionCreatorExtended = {
  name: 'todo', // <- name (required)
  schema: todoSchema, // <- schema (not required, see below)
  localDocuments: true,
  options: {
    initialDocs: [], // docs to be imported into empty collection (optional)
    schemaUrl: 'assets/data/todo.schema.json', // load schema from remote url (optional)
    replicationStateFactory: collection => {
      // provide replication state (optional)
    },
  },
};

@NgModule({
  imports: [
    // ... other imports
    NgxRxdbModule.forFeature(todoCollectionConfig),
  ],
})
export class TodosModule {
  constructor(
    @Inject(RXDB_COLLECTION) private collectionService: RxDBCollectionService<Todo>
  ) {
    this.collectionService.sync(); // INFO: collection is ready
  }
}

In your FeatureService

import { RXDB_COLLECTION } from '@ngx-odm/rxdb';
import { RxDBCollectionService } from '@ngx-odm/rxdb/collection';

@Injectable()
export class TodosService {
  private collectionService: RxDBCollectionService<Todo> =
    inject<RxDBCollectionService<Todo>>(RXDB_COLLECTION);
  // store & get filter as property of a `local` document
  filter$ = this.collectionService
    .getLocal('local', 'filterValue')
    .pipe(startWith('ALL'), distinctUntilChanged());
  // get count of documents in collection as observable
  count$ = this.collectionService.count();

  // get documents from collection as observable
  // optionally using `RxQuery` mango-queries
  todos$: Observable<Todo[]> = this.collectionService.docs();

  // add new document
  add(name: string): void {
    const payload: Todo = { guid: uuid(), name, done: false, dateCreated: Date.now() };
    this.collectionService.insert(payload);
  }

  // update property of single document
  toggle(guid: string, done: boolean): void {
    this.collectionService.set(guid, { done });
  }

  // update many documents with partial data by query
  toggleAllTodos(completed: boolean) {
    this.collectionService.updateBulk(
      { selector: { completed: { $eq: !completed } } },
      { completed }
    );
  }

  // remove many dcouments by qeury
  removeCompletedTodos(): void {
    this.collectionService.removeBulk({ selector: { completed: true } });
  }
  // ...
}

Usage (Standalone)

In your main.ts

import { provideRxDatabase } from '@ngx-odm/rxdb';
import { getRxDatabaseCreator } from '@ngx-odm/rxdb/config';

export const appConfig: ApplicationConfig = {
  providers: [
    // ... other providers
    provideRxDatabase(
      getRxDatabaseCreator({
        name: 'demo',
        localDocuments: true,
        multiInstance: true,
        ignoreDuplicate: false,
        storage: getRxStorageDexie(),
        plugins: [
          // will be loaded by together with core plugins
          RxDBDevModePlugin, // <- add only for development
          RxDBAttachmentsPlugin,
          RxDBLeaderElectionPlugin,
        ],
      })
    ),
  ],
};

bootstrapApplication(AppComponent, appConfig).catch(err => console.error(err));

In your Component

import { provideRxCollection } from '@ngx-odm/rxdb';

@Component({
  standalone: true,
  // ...
  providers: [provideRxCollection(config)],
})
export class StandaloneComponent {
  readonly todoCollection = inject(NgxRxdbCollectionService<Todo>);
}

Using sginals & signalStore from @ngrx/signals

import { signalStore } from '@ngrx/signals';
import { withEntities } from '@ngrx/signals/entities';
import { withCollectionService } from '@ngx-odm/rxdb/signals';
import { withDevtools } from '@angular-architects/ngrx-toolkit';

export const TodoStore = signalStore(
  { providedIn: 'root' },
  withDevtools('todo'),
  withEntities<Todo>(),
  // INFO: an instance of RxCollection will be provided by this
  withCollectionService<Todo, TodosFilter, RxCollectionCreatorExtended>({
    filter: 'ALL' as TodosFilter,
    collectionConfig: TodosCollectionConfig,
  }),
  ...
);

@Component({
  standalone: true,
  // ...
  providers: [TodoStore],
})
export class StandaloneComponent {
  readonly todoStore = inject(TodoStore);

  constructor() {
    effect(() => {
      const { filter, entities } = this.todoStore;
    });
  }
}

Features

By using this module you can simplify your work with RxDB in Angular application:

  • Automatically initialize db with settings
    • optionally provide db dumb to pre-fill collections
    • optionally provide array of initial documents to pre-fill collection
    • optionally provide remote location for schema and fetch it automatically before create collection (e.g. to maintain single source of truth for schema)
    • optionally provide syncronization with remote db (CouchDB, Kinto etc.) as DB options
  • Automatically initialize RxCollection for each lazy-loaded Feature module / standalone component with config
  • Work with documents via NgxRxdbCollectionService with unified methods instead of using RxCollection directly (though you still have access to RxCollection and RxDatabase instance)
    • simple methods to work database & documents (with queries)
    • simple methods to work with local documents
    • simple methods to work with attachments
    • simple replication sync initialization
  • Work with signals and entities with @ngrx/signals and @ngrx/entity (optionally zoneless) (see example)
  • Persist collection query (mango-query-syntax) in URL with new plugin query-params-plugin (in demo, set localStorage _ngx_rxdb_queryparams )
    • provide Observable of current URL (automatically for Angular)
    • simple methods to set or patch filter, sort, limit, skip

Status

Project is: in progress

Inspiration

Project inspired by

Notes

Contact

Created by @voznik - feel free to contact me!

More Resources
to explore the angular.

mail [email protected] to add your project or resources here 🔥.

Related Articles
to learn about angular.

FAQ's
to learn more about Angular JS.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory