Giter Club home page Giter Club logo

ngx-indexed-db's Introduction

ngx-indexed-db

All Contributors

Known Vulnerabilities CodeFactor Build Status CI

ngx-indexed-db is a service that wraps IndexedDB database in an Angular service combined with the power of observables.

Installation

$ npm install ngx-indexed-db

OR

$ yarn add ngx-indexed-db

Usage

Import the NgxIndexedDBModule and set up it:

import { NgxIndexedDBModule, DBConfig } from 'ngx-indexed-db';

const dbConfig: DBConfig  = {
  name: 'MyDb',
  version: 1,
  objectStoresMeta: [{
    store: 'people',
    storeConfig: { keyPath: 'id', autoIncrement: true },
    storeSchema: [
      { name: 'name', keypath: 'name', options: { unique: false } },
      { name: 'email', keypath: 'email', options: { unique: false } }
    ]
  }]
};

@NgModule({
  ...
  imports: [
    ...
    NgxIndexedDBModule.forRoot(dbConfig)
  ],
  ...
})

Migrations

import { NgxIndexedDBModule, DBConfig } from 'ngx-indexed-db';

// Ahead of time compiles requires an exported function for factories
export function migrationFactory() {
  // The animal table was added with version 2 but none of the existing tables or data needed
  // to be modified so a migrator for that version is not included.
  return {
    1: (db, transaction) => {
      const store = transaction.objectStore('people');
      store.createIndex('country', 'country', { unique: false });
    },
    3: (db, transaction) => {
      const store = transaction.objectStore('people');
      store.createIndex('age', 'age', { unique: false });
    }
  };
}

const dbConfig: DBConfig  = {
  name: 'MyDb',
  version: 3,
  objectStoresMeta: [{
    store: 'people',
    storeConfig: { keyPath: 'id', autoIncrement: true },
    storeSchema: [
      { name: 'name', keypath: 'name', options: { unique: false } },
      { name: 'email', keypath: 'email', options: { unique: false } }
    ]
  }, {
    // animals added in version 2
    store: 'animals',
    storeConfig: { keyPath: 'id', autoIncrement: true },
    storeSchema: [
      { name: 'name', keypath: 'name', options: { unique: true } },
    ]
  }],
  // provide the migration factory to the DBConfig
  migrationFactory
};

@NgModule({
  ...
  imports: [
    ...
    NgxIndexedDBModule.forRoot(dbConfig)
  ],
  ...
})

NgxIndexedDB service

Import and inject the service:

import { NgxIndexedDBService } from 'ngx-indexed-db';

...
  export class AppComponent {
    constructor(private dbService: NgxIndexedDBService){
    }
  }

API

We cover several common methods used to work with the IndexedDB

add(storeName: string, value: T, key?: any): Observable<T & {id: any}>

Adds new entry in the store and returns item added

  • @param storeName The name of the store to add the item
  • @param value The entry to be added
  • @param key The optional key for the entry

It publishes in the observable the key value of the entry

this.dbService
  .add('people', {
    name: `Bruce Wayne`,
    email: `[email protected]`,
  })
  .subscribe((key) => {
    console.log('key: ', key);
  });

In the previous example I'm using undefined as the key because the key is configured in the objectStore as auto-generated.

bulkAdd(storeName: string, values: Array<T & { key?: any }>): Observable<number[]>

Adds new entries in the store and returns its key

  • @param storeName The name of the store to add the item
  • @param values The entries to be added containing optional key attribute
this.dbService
  .bulkAdd('people', [
    {
      name: `charles number ${Math.random() * 10}`,
      email: `email number ${Math.random() * 10}`,
    },
    {
      name: `charles number ${Math.random() * 10}`,
      email: `email number ${Math.random() * 10}`,
    },
  ])
  .subscribe((result) => {
    console.log('result: ', result);
  });

bulkDelete(storeName: string, keys: Key[]): Observable<number[]>

Delete multiple items in the store

  • @param storeName The name of the store to delete the items
  • @param keys The entries keys to be deleted
  this.dbService.bulkDelete('people', [5, 6]).subscribe((result) => {
    console.log('result: ', result);
  });

bulkGet(storeName: string, keys: Array): Observable<T[]>

Retrieve multiple entries in the store

  • @param storeName The name of the store to retrieve the items
  • @param keys The ids entries to be retrieve
this.dbService.bulkGet('people', [1, 3, 5]).subscribe((result) => {
    console.log('results: ', result);
  });

bulkPut(storeName: string, values: Array<T & { key?: any }>): Observable<number[]>

Adds or updates a record in store with the given value and key. Return all items present in the store

  • @param storeName The name of the store to update
  • @param items The values to update in the DB

@Return The return value is an Observable with the primary key of the object that was last in given array

@error If the call to bulkPut fails the transaction will be aborted and previously inserted entities will be deleted

this.dbService.bulkPut('people', people).subscribe((result) => {
  console.log('result: ', result);
});

update(storeName: string, value: T): Observable<T[]>

Adds or updates a record in store with the given value and key. Return item updated

  • @param storeName The name of the store to update
  • @param value The new value for the entry
this.dbService
  .update('people', {
    id: 1,
    email: '[email protected]',
    name: 'Luke Skywalker',
  })
  .subscribe((storeData) => {
    console.log('storeData: ', storeData);
  });

getByKey(storeName: string, key: IDBValidKey): Observable

Returns entry by key.

  • @param storeName The name of the store to query
  • @param key The entry key
this.dbService.getByKey('people', 1).subscribe((people) => {
  console.log(people);
});

getAll(storeName: string): Observable<T[]>

Return all elements from one store

  • @param storeName The name of the store to select the items
this.dbService.getAll('people').subscribe((peoples) => {
  console.log(peoples);
});

getByIndex(storeName: string, indexName: string, key: IDBValidKey): Observable

Returns entry by index.

  • @param storeName The name of the store to query
  • @param indexName The index name to filter
  • @param key The entry key.
this.dbService.getByIndex('people', 'name', 'Dave').subscribe((people) => {
  console.log(people);
});

createObjectStore(storeSchema: ObjectStoreMeta, migrationFactory?: () => { [key: number]: (db: IDBDatabase, transaction: IDBTransaction) => void }): void

Allows to crate a new object store ad-hoc

  • @param storeName The name of the store to be created
  • @param migrationFactory The migration factory if exists
const storeSchema: ObjectStoreMeta = {
  store: 'people',
  storeConfig: { keyPath: 'id', autoIncrement: true },
  storeSchema: [
    { name: 'name', keypath: 'name', options: { unique: false } },
    { name: 'email', keypath: 'email', options: { unique: false } },
  ],
};

this.dbService.createObjectStore(storeSchema);

count(storeName: string, keyRange?: IDBValidKey | IDBKeyRange): Observable

Returns the number of rows in a store.

  • @param storeName The name of the store to query
  • @param keyRange The range value and criteria to apply.
this.dbService.count('people').subscribe((peopleCount) => {
  console.log(peopleCount);
});

deleteObjectStore(storeName: string): Observable

Delete the store by name, return true or false.

  • @param storeName The name of the store to query
this.dbService.deleteObjectStore(this.storneNameToDelete);

delete(storeName: string, key: Key): Observable<T[]>

Returns all items from the store after delete.

  • @param storeName The name of the store to have the entry deleted
  • @param key The key of the entry to be deleted
this.dbService.delete('people', 3).subscribe((allPeople) => {
  console.log('all people:', allPeople);
});

deleteByKey(storeName: string, key: Key): Observable

Returns true if the delete completes successfully.

  • @param storeName The name of the store to have the entry deleted
  • @param key The key of the entry to be deleted
this.dbService.deleteByKey('people', 3).subscribe((status) => {
  console.log('Deleted?:', status);
});

openCursor(storeName: string, keyRange?: IDBKeyRange, direction?: IDBCursorDirection): Observable

Returns the open cursor event

  • @param storeName The name of the store to have the entries deleted
  • @param keyRange The key range which the cursor should be open on
  • @param direction IDB Cursor Direction to work with, default to next
this.dbService.openCursor('people', IDBKeyRange.bound("A", "F")).subscribe((evt) => {
    var cursor = (evt.target as IDBOpenDBRequest).result;
    if(cursor) {
        console.log(cursor.value);
        cursor.continue();
    } else {
        console.log('Entries all displayed.');
    }
});

openCursorByIndex(storeName: string, indexName: string, keyRange: IDBKeyRange, direction?: IDBCursorDirection, mode?: DBMode): Observable

Open a cursor by index filter.

  • @param storeName The name of the store to query.
  • @param indexName The index name to filter.
  • @param keyRange The range value and criteria to apply on the index.
  • @param direction IDB Cursor Direction to work with, default to next
  • @param mode DB Mode to work with, default to readonly
this.dbService.openCursorByIndex('people', 'name', IDBKeyRange.only('john')).subscribe((evt) => {
    var cursor = (evt.target as IDBOpenDBRequest).result;
    if(cursor) {
        console.log(cursor.value);
        cursor.continue();
    } else {
        console.log('Entries all displayed.');
    }
});

getAllByIndex(storeName: string, indexName: string, keyRange: IDBKeyRange): Observable<T[]>

Returns all items by an index.

  • @param storeName The name of the store to query
  • @param indexName The index name to filter
  • @param keyRange The range value and criteria to apply on the index.
this.dbService.getAllByIndex('people', 'name', IDBKeyRange.only('john')).subscribe((allPeopleByIndex) => {
  console.log('All: ', allPeopleByIndex);
});

getDatabaseVersion(): Observable

Returns the current database version.

this.dbService.getDatabaseVersion().pipe(
  tap(response => console.log('Versione database => ', response)),
  catchError(err => {
    console.error('Error recover version => ', err);
    return throwError(err);
  })
).subscribe();

clear(storeName: string): Observable

Returns true if successfully delete all entries from the store.

  • @param storeName The name of the store to have the entries deleted
this.dbService.clear('people').subscribe((successDeleted) => {
  console.log('success? ', successDeleted);
});

deleteDatabase(): Observable

Returns true if successfully delete the DB.

this.dbService.deleteDatabase().subscribe((deleted) => {
  console.log('Database deleted successfully: ', deleted);
});

License

Released under the terms of the MIT License.

Contributors ✨

Thanks goes to these wonderful people (emoji key):


Angelo Parziale

🚧 πŸ’»

Charles Assunção

πŸ’» πŸ“– 🚧

coolweb

🚧

This project follows the all-contributors specification. Contributions of any kind welcome!

ngx-indexed-db's People

Contributors

allcontributors[bot] avatar aparzi avatar assuncaocharles avatar coolweb avatar cricciardi avatar dependabot[bot] avatar desmondchou avatar devidw avatar gabriel949 avatar haidarvladyslav avatar irsali avatar jcox86 avatar kencoken avatar pascalmh avatar takuma-watanabe avatar yasinkocak avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

ngx-indexed-db's Issues

Handling of database deletion while app is running

If the indexeddb is deleted during app lifetime for any reasons, the next query to indexeddb leads to its recreation with no stores but the correct version number.
In such situation, the only way to recover is to delete the database manually again and to restart the app while in such situation (0 stores and Missing store error), the CreateObjectStore method should be called.

greg

An in-range update of tar is breaking the build 🚨

The devDependency tar was updated from 5.0.2 to 5.0.3.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

tar is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

Commits

The new version differs by 2 commits.

  • 16d07b2 5.0.3
  • 5e8dfa4 Set more portable 'mode' value in portable mode

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

deleteDatabase taking long time

I'm adding thousands of items into IndexedDB. When trying to delete database with deleteDatabase(), returned Promise can take minutes to resolve. I did research about this issue and I think this is because database connections are not closed. And only after browser garbage collection is finished database is deleted.

What do you think, would closing connections after inserting / getting from IndexedDB improve this? Any change of getting it implemented?

Concurrency issue with multiple stores

Consider the following code (a real Angular example might be components in different NgZones calling two "data" service methods to get a result).

this.ngxDatabase.currentStore = "users";
this.ngxDatabase.getAll()
  .then(users => {
    // do something with users
  });

this.ngxDatabase.currentStore = "animals";
this.ngxDatabase.getAll()
  .then(animals => {
    // do something with animals
  });

This creates a race condition because the call to users will return the animals if the currentStore is updated before the first operation completes.

I think there is a fundamental issue with having the shared mutable currentStore field, as it can be mutated while an operation is still in process.
I think a good (potentially breaking) change would be to pass the "store" to each and every operation as a parameter (rather than storing it as a shared mutable field on the NgxIndexedDBService):

this.ngxDatabase.getAll("users")
  .then(users => {
    // do something with users
  });

this.ngxDatabase.getAll("animals")
  .then(animals => {
    // do something with animals
  });

That way the "store" will be scoped to that operation, and operations won't clobber each other by updating that shared mutable field.

As a workaround for now I am saving the "current operation" promise as a field in my "data" service and am chaining each subsequent operation to it so they are executed sequentially (avoiding the clobbering of the currentStore):

private currentOperation: Promise<any> = Promise.resolve();

public example() {
  this.execute("users", () => {
    return this.ngxDatabase.getAll();
  }).then(users => {
    // do stuff with users
  });

  this.execute("animals", () => {
    return this.ngxDatabase.getAll();
  }).then(users => {
    // do stuff with animals
  });

private execute<T>(store: string, callback: () => Promise<T>): Promise<T> {
  return this.currentOperation = this.currentOperation.then(_ => {
    this.ngxDatabase.currentStore = store;
    return callback();
  })
}

}

If you are happy with my suggestion I can create a PR with the breaking change, and a new version could be created.
Or we could come up with an additive API that just adds new methods that take in the "store" parameter using the new logic, while leaving the old logic alone for backwards compatibility. Let me know what your thoughts are.

NPM packages are broken (2.0.0+)

The published packages contain only the source code.
Therefore it is not possible to use any package with version 2.0.0+

.
β”œβ”€β”€ angular.json
β”œβ”€β”€ docs
β”‚Β Β  β”œβ”€β”€ assets
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ css
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ main.css
β”‚Β Β  β”‚Β Β  β”‚Β Β  └── main.css.map
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ images
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ [email protected]
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ icons.png
β”‚Β Β  β”‚Β Β  β”‚Β Β  β”œβ”€β”€ [email protected]
β”‚Β Β  β”‚Β Β  β”‚Β Β  └── widgets.png
β”‚Β Β  β”‚Β Β  └── js
β”‚Β Β  β”‚Β Β      β”œβ”€β”€ main.js
β”‚Β Β  β”‚Β Β      └── search.js
β”‚Β Β  β”œβ”€β”€ classes
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ _lib_ngx_indexed_db_.dbwrapper.html
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ _lib_ngx_indexed_db_.ngxindexeddb.html
β”‚Β Β  β”‚Β Β  └── _lib_ngx_indexed_db_.utils.html
β”‚Β Β  β”œβ”€β”€ enums
β”‚Β Β  β”‚Β Β  └── _lib_ngx_indexed_db_.dbmode.html
β”‚Β Β  β”œβ”€β”€ globals.html
β”‚Β Β  β”œβ”€β”€ index.html
β”‚Β Β  β”œβ”€β”€ interfaces
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ _lib_ngx_indexed_db_.indexdetails.html
β”‚Β Β  β”‚Β Β  └── _lib_ngx_indexed_db_.options.html
β”‚Β Β  └── modules
β”‚Β Β      β”œβ”€β”€ _lib_ngx_indexed_db_.html
β”‚Β Β      └── _public_api_.html
β”œβ”€β”€ e2e
β”‚Β Β  β”œβ”€β”€ protractor.conf.js
β”‚Β Β  β”œβ”€β”€ src
β”‚Β Β  β”‚Β Β  β”œβ”€β”€ app.e2e-spec.ts
β”‚Β Β  β”‚Β Β  └── app.po.ts
β”‚Β Β  └── tsconfig.e2e.json
β”œβ”€β”€ LICENSE
β”œβ”€β”€ ngx-indexed-db-2.0.1.tgz
β”œβ”€β”€ package.json
β”œβ”€β”€ projects
β”‚Β Β  └── ngx-indexed-db
β”‚Β Β      β”œβ”€β”€ karma.conf.js
β”‚Β Β      β”œβ”€β”€ ng-package.json
β”‚Β Β      β”œβ”€β”€ ng-package.prod.json
β”‚Β Β      β”œβ”€β”€ package.json
β”‚Β Β      β”œβ”€β”€ src
β”‚Β Β      β”‚Β Β  β”œβ”€β”€ lib
β”‚Β Β      β”‚Β Β  β”‚Β Β  └── ngx-indexed-db.ts
β”‚Β Β      β”‚Β Β  β”œβ”€β”€ public_api.ts
β”‚Β Β      β”‚Β Β  └── test.ts
β”‚Β Β      β”œβ”€β”€ tsconfig.lib.json
β”‚Β Β      β”œβ”€β”€ tsconfig.spec.json
β”‚Β Β      └── tslint.json
β”œβ”€β”€ README.md
β”œβ”€β”€ tsconfig.json
└── tslint.json

Working with multiple stores in new version.

Hi,
We have a multiple stores and one dao service for using indexxed db. On earlier versions (ex. 2.6.1) for getting for ex. fruits we have used getAll('friutsstore') . But for latest version as far as understand we must have ngxindexeddb service which keeps current store name inside service. How we can use with multiple stores on latest versions? Could we create multiple dbservices for every stores?
Thank you.

An in-range update of @types/node is breaking the build 🚨

The devDependency @types/node was updated from 12.12.15 to 12.12.16.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of @angular/cli is breaking the build 🚨

The devDependency @angular/cli was updated from 9.0.3 to 9.0.4.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@angular/cli is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

Release Notes for v9.0.4

Commits

@angular/cli (9.0.4)

Commit Description Notes
expand locale pattern in all schemas for all cases
directly remove ansi color codes when no color support

@schematics/angular (9.0.4)

Commit Description Notes
Allow empty string in the type option

@angular-devkit/schematics-cli (0.900.4)

Commit Description Notes
provide resolvePaths to NodeWorkflow [Closes #17067]

@angular-devkit/build-angular (0.900.4)

Commit Description Notes
allow function in filename while changing the name of compiling chunks [Closes #17087]
limit the amount of CPUs used by workers
fix autoprefixer comments support in scss [Closes #17041]
baseHref with protocol and localize option
update core-js to 3.6.4 [Closes #16955]

@angular/pwa (0.900.4)

Commit Description Notes
use relative paths in webmanifest

@ngtools/webpack (9.0.4)

Commit Description Notes
don't elide decorated method parameter type reference [Closes #17080]
always use VE for deprecated string route discovery
handle union type with a nullable argument


Special Thanks

Alan Agius, Sachin Grover, Charles Lyding, Doug Parker, Cyrille Tuzi, Schneider

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

NgxIndexedDBModule.forRoot() unusable in production build.

Hi,

I followed the readme made available at https://www.npmjs.com/package/ngx-indexed-db and created an angular8 project that attempts to inject the NgxIndexedDBModule the way the readme suggests. I'm attaching two screenshots, one consisting of the readme I followed, and the other consisting of code that is raising errors, within app.module.ts.

My Error:

ERROR in Error during template compile of 'AppModule' Function calls are not supported in decorators but 'NgxIndexedDBModule' was called. Unexpected value 'undefined' imported by the module 'AppModule in C:/Users/REDACTED/REDACTED/REDACTED/REDACTED/REDACTED/src/app/app.module.ts' Error during template compile of 'AppModule' Function calls are not supported in decorators but 'NgxIndexedDBModule' was called.

Look for a "THIS CAUSES THE ERROR" clause within the next section called "My app.module.ts".

My app.module.ts:
(you can visit https://pastebin.com/KFgymh7f if it is not very readable in this post)

//--------------------
`import { DBConfig } from 'ngx-indexed-db';
import { NgxIndexedDBModule } from 'ngx-indexed-db';
import { NgModule } from '@angular/core';

const dbConfig: DBConfig = {name: 'MyDb', version: 1, objectStoresMeta: [
{
store: 'people',
storeConfig: { keyPath: 'id', autoIncrement: true },
storeSchema: [
{ name: 'name', keypath: 'name', options: { unique: false } },
{ name: 'email', keypath: 'email', options: { unique: false } }
]
}
]};

@NgModule({
declarations: [],
imports: [
NgxIndexedDBModule.forRoot(dbConfig), //THIS CAUSES THE ERROR
],
providers: [],
})
export class AppModule {}`
//------------------

The sole instantiation of a NgxIndexedDBService itself is not even relevant - the application does not reach the point of attempting to instantiate an app.component.ts.

ngindexeddb2
ngindexeddb

Cannot find module ngx-indexed-db

Hi, i'm importing it in my angular 7 service class, but building it always throws "webpackMissingModule() { var e = new Error("**Cannot find module "ngx-indexed-db**""); e.code = 'MODULE_NOT_FOUND'; throw e; }"

An in-range update of @types/node is breaking the build 🚨

The devDependency @types/node was updated from 13.5.0 to 13.5.1.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of ng-packagr is breaking the build 🚨

The devDependency ng-packagr was updated from 4.5.0 to 4.6.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

ng-packagr is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

On the struggle Bus

I've been able to create a database and create an object store, but I can't seem to add an entry. Here is my code:

  saveMovie(payload: object) {
    console.log(payload);
    const db = new NgxIndexedDB('mobileRecall', 1);
    db.openDatabase(1, evt => {
      const objectStore = evt.currentTarget.result.createObjectStore('movies', { keyPath: 'id', autoIncrement: true })
      .then(db.add('movies', payload).then(() => evt('success'), (err) => console.log(err)));
    });

Payload is this object

{
  Poster: "https://m.media-amazon.com/images/M/MV5BNDY3NzQ0NjYxM15BMl5BanBnXkFtZTcwMDkzODM2Mw@@._V1_SX300.jpg"
Title: "The Sorcerer's Apprentice"
Type: "movie"
Year: "2010"
imdbID: "tt0963966"
}

Here are the entities being created

screen shot 2019-02-10 at 2 28 40 pm

Hoping someone out there can put together a fully working sample. I'd be ahppy to contribute it back to the readme here.

Getting error in db.deleteDatabase()

TypeError: Cannot read property 'close' of undefined
at ngx-indexed-db.js:254
at new ZoneAwarePromise (zone-evergreen.js:876)
at NgxIndexedDB.deleteDatabase (ngx-indexed-db.js:248)
at IndexedDbService.dropdb (indexed-db.service.ts:21)
at login.component.ts:84
at ZoneDelegate.invoke (zone-evergreen.js:359)
at Object.onInvoke (core.js:34201)
at ZoneDelegate.invoke (zone-evergreen.js:358)
at Zone.run (zone-evergreen.js:124)
at zone-evergreen.js:855

On line this.dbWrapper.db.close();

Compile-time error with code in Readme.md (and solution)

Overview

In the README.md file the first code sample has the following:

import { NgxIndexedDBModule } from 'ngx-indexed-db';

const dbConfig: DBConfig  = {

This produces the following error:

ERROR in src/app/app.module.ts:13:17 - error TS2304: Cannot find name 'DBConfig'.

Repro

  1. Start a new Angular project.
  2. Add the ng-indexed-db module.
  3. Modify the Angular project with the first code sample from this project's README.md

Expected

That I get no compile-time warnings.

Actual

I get a compile time warning that it can't find 'DBConfig'.

Proposed Solution

I'm not very familiar with TypeScript or Angular, so takes this with a grain of salt, but when I added an import for DBConfig then the problem went away:

import { NgxIndexedDBModule } from 'ngx-indexed-db';
import { DBConfig } from 'ngx-indexed-db';

const dbConfig: DBConfig  = {

There might be a better way to do this...

An in-range update of @angular-devkit/build-angular is breaking the build 🚨

The devDependency @angular-devkit/build-angular was updated from 0.900.3 to 0.900.4.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@angular-devkit/build-angular is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

IE11 support

Not working with ie11.
Falling in error, and not resolving data from storage.

Im on mobile, when touch my pc, add more info.
Tx for understanding

Migration: getByKey has been removed

Hi !
I was looking into this lib and noticed that the getByKey function is not available (yet?) in the NgxIndexedDBService. It was in previous versions, but since the refactor it's just gone. Even though it's still referenced in the documentation.

I get that the 3.0 is probably still in progress since there was no release yet, but I thought it was a good idea to point it out.

Migrations

Hello there. would it be possible to have a example of an migration to a newer version in the readme?

An in-range update of @types/jasmine is breaking the build 🚨

The devDependency @types/jasmine was updated from 3.3.16 to 3.4.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/jasmine is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of @types/node is breaking the build 🚨

The devDependency @types/node was updated from 13.1.6 to 13.1.7.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of @types/node is breaking the build 🚨


☝️ Important announcement: Greenkeeper will be saying goodbye πŸ‘‹ and passing the torch to Snyk on June 3rd, 2020! Find out how to migrate to Snyk and more at greenkeeper.io


The devDependency @types/node was updated from 13.7.7 to 13.9.0.

🚨 View failing branch.

This version is covered by your current version range and after updating it in your project the build failed.

@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Property 'count' does not exist on type 'NgxIndexedDBService'.ts(2339)

import { NgxIndexedDBService } from 'ngx-indexed-db';

export class AppComponent implements OnInit {

 constructor(
    private operationSrv: OperationsService, public accountsService: AccountsService,
    private dbService: NgxIndexedDBService) {
      dbService.currentStore = IDBCuenta;
}

ngOnInit() 
this.dbService.count().then(...); // compile error
}

Property 'count' does not exist on type 'NgxIndexedDBService'.ts(2339)

The documentation indicates I can use count() over dbService, but the library doesn't include that method.

Any workaround to get the records count?

Data is not getting saved in Microsoft edge browser

Here is my code implemented for saving data into indexed db, but data is not getting saved.
please refer below code and error message.

this.dbService.add('people', obj).then(() => {
console.log('saved successfully');
}, error => {
console.log(error);
});

image001

Adding Data to Multiple Stores Sequentially

Is it possible to add data to object stores sequentially? I have an issue where I need to add data to different stores, but the data just gets added to the store that was last set and throws an error:

Error: Uncaught (in promise): Event: {"isTrusted":true}

Here is a StackBlitz example

Thanks

Prevent race condition on creation of database

The creation of the database is done in your forroot that call the ngx indexed db service constructor which create the db in asynchronous action. If some code try to access the database, the database might not be created.
A solution is to create a separate method to create the database with async return like promise and call this method in an APP_INITILAZER provider in your module.

DataError occur when I call openCusor with no keyRange in IE11.

Hi.

When I call NgxIndexedDBService.openCusor with no keyRange in IE11, DataError occur.

NgxIndexedDBService.openCusor('store name', (event) => {});

This code executed successfully in Chrome. But error occured in IE11.

And I found below code that NgxIndexedDBService.openCursor() function pass keyRange argument to IDBObjectStore.openCursor() function.

// ngx-indexed-db.service.ts:169
request = objectStore.openCursor(keyRange);

I think it seems IDBObjectStore.openCursor() function checks that argument was passed or not.

So if I call IDBObjectStore.openCursor() with explicit undefined argument in IE11, It throws DataError.

It can be reproducted by executing below code in IE11.

var request = indexedDB.open('TestDB', 1);
request.onupgradeneeded = function(event) { 
  var db = request.result;
  var store = db.createObjectStore('TestStore', { keyPath: 'id' });
  var index = store.createIndex('indexName', 'name');
  store.put({});
};
request.onsuccess = function(event) {
  var db = request.result;
  var transaction = db.transaction(['TestStore'], "readonly");
  var objectStore = transaction.objectStore('TestStore');
  var cursor = objectStore.openCursor(undefined); // SCRIPT5022: DataError
//var cursor = objectStore.openCursor(); // It is OK
//var cursor = objectStore.openCursor(null); // It is OK, too.
};

In the document getAll has 3 parameters but cannot find in code

Document states
"getAll(storeName, keyRange, indexDetails)"

but version 4.0.3 is:


import { Key } from './ngx-indexed-db';
import { DBConfig } from './ngx-indexed-db.meta';
export declare class NgxIndexedDBService {
    private dbConfig;
    indexedDB: any;
    constructor(dbConfig: DBConfig);
    add<T>(storeName: string, value: T, key?: any): Promise<number>;
    getByKey<T>(storeName: string, key: any): Promise<any>;
    getByID<T>(storeName: string, id: string | number): Promise<T>;
    getAll<T>(storeName: string): Promise<T[]>;
    update<T>(storeName: string, value: T, key?: any): Promise<any>;
    deleteRecord(storeName: string, key: Key): Promise<any>;
    clear(storeName: string): Promise<any>;
    delete(storeName: string, key: any): Promise<any>;
    deleteDatabase(): Promise<unknown>;
    openCursor(storeName: string, cursorCallback: (event: Event) => void, keyRange?: IDBKeyRange): Promise<void>;
    getByIndex(storeName: string, indexName: string, key: any): Promise<any>;
    count(storeName: string, keyRange?: IDBValidKey | IDBKeyRange): Promise<any>;
}

How do we use the other 2 parameters?

Thanks.

Unable to delete database

Hi, there is no option to delete a database, even updating the db version didn't get rid of the old database.

get not working

return on console: You need to use the openDatabase function to create a database before you query it!

my code;

public db: any;
constructor() {
this.db = new NgxIndexedDB('healthdome', 1);
}

openDataBase(version: number, evt?: any) {

  this.db.openDatabase(version, evt => {
    let objectPlayerStore = evt.currentTarget.result.createObjectStore('players', { keyPath: 'id', autoIncrement: false });  
    objectPlayerStore.createIndex('person', 'person', { unique: false });
    console.log(objectPlayerStore)
  }, error => { console.log(error)}) 

}

getAll(storeName: string) {
this.db.getAll(storeName).then(
obj => {
return obj;
},
error => {
console.log(error);
}
);
}

on my app.component.
this._ngxIndexedDbService.openDataBase(1);

this._ngxIndexedDbService.getAll("players")

Error on Event isTrusted

Hi,

I am getting an error in using db.add function with angular7 implementation:
ERROR Error: Uncaught (in promise): Event: {"isTrusted":true}
at M (polyfills.6730d4c9a2c69ac6cad9.js:1)
at polyfills.6730d4c9a2c69ac6cad9.js:1
at IDBTransaction.abort [as __zone_symbol__ON_PROPERTYabort] (4.26eb8e265adffe5bd9d5.js:1)
at IDBTransaction.O (polyfills.6730d4c9a2c69ac6cad9.js:1)
at t.invokeTask (polyfills.6730d4c9a2c69ac6cad9.js:1)
at Object.onInvokeTask (main.08bd23ad706e75f29b00.js:1)
at t.invokeTask (polyfills.6730d4c9a2c69ac6cad9.js:1)
at e.runTask (polyfills.6730d4c9a2c69ac6cad9.js:1)
at e.invokeTask [as invoke] (polyfills.6730d4c9a2c69ac6cad9.js:1)
at m (polyfills.6730d4c9a2c69ac6cad9.js:1)

Any idea? It doesn't add to my indexedDB table.

How do we do an update based on key?

Hi there.

I was wondering how I can update an entry? I am able to add it to the db but not updated it.
I have a simple list I want to save for offline use.

Below is the example, I have commented on sections in the code to explain it better. I hope it helps. I feel like I am so close and missing something.

Thanks for the help

let db = new NgxIndexedDB('list', 1);
db.openDatabase(1, evt => {
  let objectStore = evt.currentTarget.result.createObjectStore('list', { keyPath: 'id', autoIncrement: true });
}).then(function () {
  db.getByKey('list', 1).then( // only want to keep 1 list in the db based on the id 1
    data => {
      if(_.isUndefined(data)){ // no data so lets add it (this works great)
        console.log('adding')
        db.add('list', listData).then(
          () => {
            console.log('yay works and in the db');  
          },
          error => {
            console.log('dataAddedError');
          }
        );
      } else {
        console.log('already have data, lets update')
        db.update('list', listData, 1).then( // update based on key id NOT WORKING HERE
          () => {    
            console.log('dataUpdated'); // this does not fire off 
          },
          error => {
            console.log'dataUpdateError'); // always fails
          }
        );
      }            
    },
    error => {
      console.log(error);
    }
  );
});

Upgrade to Angular 8 Fails

I am trying to upgrade my project to angular 8 but am getting the following error;

Angular8Upgrade

Will this package be upgraded to work with Angular 8?

can a compound key be used?

Hi,

So, the native indexed-db can use a array as keypath. Could this be added? currently it's acepting a string only, would it break anything?

Would compile and do a pull request, but haven't been able to run ng test successfully...

Add a method to query non-unique indexes

Hello

it would be a good idea to add an openCursorByIndex method which would allow specifying the name of the index on which the keyrange is applied.

This would be useful to make query on non-unique indexes.

greg

Redirect after db.add and show data

Hi, im new with Angular but i make simple app to add tasks. This is my service file:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Router} from '@angular/router';

import { NgxIndexedDB } from 'ngx-indexed-db';

@Injectable({
  providedIn: 'root'
})
export class TasksService {

  constructor(private http: HttpClient, private router: Router) { }

  addTask(Nazwa, Ilosc) {
    const db = new NgxIndexedDB('Tasks', 1);
    const obj = {
      Nazwa,
      Ilosc
    };
    console.log(obj);

    db.openDatabase(1, evt => {
      const objectStore = evt.currentTarget.result.createObjectStore('tasklist', { keyPath: 'id', autoIncrement: true });

      objectStore.createIndex('nazwa', 'nazwa', { unique: false });
      objectStore.createIndex('ilosc', 'ilosc', { unique: false });
    });

    db.openDatabase(1).then(function() {
      db.add('tasklist', { nazwa: Nazwa, ilosc: Ilosc }).then(
        () => {
          this.router.navigate(['task']);
        },
        error => {
          console.log(error);
        }
      );
    });
  }
  getTask() {
    const db = new NgxIndexedDB('Tasks', 1);

    db.openDatabase(1, evt => {
      const objectStore = evt.currentTarget.result.createObjectStore('tasklist', { keyPath: 'id', autoIncrement: true });

      objectStore.createIndex('nazwa', 'nazwa', { unique: false });
      objectStore.createIndex('ilosc', 'ilosc', { unique: false });
    });

    db.openDatabase(1).then(function() {
      db.getAll('tasklist').then(
        tasks => {
          return tasks;
        },
        error => {
          console.log(error);
        }
      );
    });
  }
}
  1. How to make redirect after add new entry this.router.navigate(['task']); ?
  2. How to get lists using getTask() function?

In my get component i have this:

import { Component, OnInit } from '@angular/core';
import { TasksService } from '../tasks.service';

@Component({
  selector: 'app-task-get',
  templateUrl: './task-get.component.html',
  styleUrls: ['./task-get.component.css']
})
export class TaskGetComponent implements OnInit {

  constructor(private ps: TasksService) {}

  ngOnInit() {
    console.log(this.ps.getTask());
  }
}

In web console i get undefined. Thanks for any help.

getAll function doesn't retrieve value

Hello,

I try to use this plugin in my Angular 8 project.
I registered the Module as expected in Readme.
Then I use the service like this :

@Injectable({
    providedIn: "roo"'
})
export class RequestCacheHelper {
    constructor(private dbService: NgxIndexedDBService) {
        this.dbService.currentStore = 'request';
    }
...
    retryRequests() {
        this.dbService.getAll().then(
            requestEntityList => {
                if (requestEntityList) {
                    // do something
                }
            });
    }

The result "requestEntityList" is always undefined. I look through your code and I discover that in "NgxIndexedDBService" you retrieve the value like that

request.onsuccess = function({ target: { successResult } }: any) {
					resolve(successResult as T[]);
				};

whereas it should be, I think :

request.onsuccess = function({ target: { success } }: any) {
					resolve(success as T[]);
				};

Example confusion

Your migration example isn't making any sense to me. You're grabbing the people table, and then adding an index on country and age...neither of which are shown as being columns in the tables.

Also, what's the difference between name and keypath on the storeSchema? Seems like they're just always the same.

Firefox not working

I have this all set up nicely, works for chrome and safari, however Firefox doesnt seem to work.

It breaks on
db.openDatabase

After digging around, the error reported is
InvalidStateError: A mutation operation was attempted on a database that did not allow mutations.

stackoverflow

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.