Giter Club home page Giter Club logo

angular-indexeddb's Introduction

angular-indexedDB

An angularjs serviceprovider to utilize indexedDB with angular

####Important: This repository isn't maintained by me anymore. Look over here for current versions, as Bram Whillock took over as main contributor.

Installation

For installation the use of Bower is recommended.

Bower

Call the following command on your command line:

bower install --save angularjs-indexedDB

And add the following line to your html file, for example index.html:

<script src="components/angular-indexedDB/src/indexeddb.js"></script>

Manual

  • Download file.
  • Add the following line to your html file:
<script src="indexeddb.js"></script>

Usage

Normally, and as a recommendation, you have only one indexedDB per app. Thus in your app.js where you define your module, you do:

angular.module('myModuleName', ['xc.indexedDB'])
  .config(function ($indexedDBProvider) {
    $indexedDBProvider
      .connection('myIndexedDB')
      .upgradeDatabase(myVersion, function(event, db, tx){
        var objStore = db.createObjectStore('people', {keyPath: 'ssn'});
        objStore.createIndex('name_idx', 'name', {unique: false});
        objStore.createIndex('age_idx', 'age', {unique: false});
      });
  });

The connection method takes the databasename as parameter, the upgradeCallback has 3 parameters: function callback(event, database, transaction). For upgrading your db structure, see https://developer.mozilla.org/en-US/docs/IndexedDB/Using_IndexedDB.

You can also define your own error handlers, overwriting the default ones, which log to console.

Inside your controller you use $indexedDB like this:

angular.module('myModuleName')
  .controller('myControllerName', function($scope, $indexedDB) {
    
    $scope.objects = [];
    
    var OBJECT_STORE_NAME = 'people';  
        
    /**
     * @type {ObjectStore}
     */
    var myObjectStore = $indexedDB.objectStore(OBJECT_STORE_NAME);
    
    myObjectStore.insert({"ssn": "444-444-222-111","name": "John Doe", "age": 57}).then(function(e){...});
    
    myObjectStore.getAll().then(function(results) {  
      // Update scope
      $scope.objects = results;
    });

  /**
   * execute a query:
   * presuming we've an index on 'age' field called 'age_idx'
   * find all persons older than 40 years
   */
   
   var myQuery = $indexedDB.queryBuilder().$index('age_idx').$gt(40).$asc.compile();
   myObjectStore.each(myQuery).then(function(cursor){
     cursor.key;
     cursor.value;
     ...
   });
  });

QueryBuilder aka IDBKeyRange maybe needs some revision. This is all the info you get for now, for more read the code, it's ndoc-annotated!

Important note: this software is in alpha state and therefore it's used at your own risk, don't make me liable for any damages or loss of data!

Status Update: I'm sorry to say that I've abandoned angularJS for now and therefore have no plans for features or updates. This may change in the future. Apart from that I will apply updates submitted as pull requests when I find the time and see use.

Anyone willing to join as active developer is welcome to drop me a note and help keep this project alive.

angular-indexeddb's People

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  avatar  avatar  avatar  avatar  avatar

angular-indexeddb's Issues

transaction.oncomplete vs request.onsuccess

I have test cases that do something like:

indexeddb.delete(...).then (function() {
indexeddb.insert(...).then(function() {
indexeddb.find(...).then(function(data){};
};
};

The result is intermittent. Sometimes 'data' correctly finds the value, but sometimes 'data' is undefined.

I "fixed" this by making sure that the transaction has been completed before resolving the promise:

req.onsuccess = function(e) {
store.transaction.oncomplete = function(){
$rootScope.$apply(function(){
d.resolve(e.target.result);
});
}
};

I don't know the sequence of when transaction.oncomplete and request.onsuccess functions are called. I'm very new to indexeddb (well, and angular) so I'm not sure what the best approach is.

About your example

Hi

Could you provide an online demo please?

When I tried it by myself, nothing get inserted and then() is never called and of course I aint got any log in console (same on FF and Chrome)

Thanks, have a nice day

NB : I hope this is the right place for asking

onsuccess vs oncomplete

It seems in indexdDB if a write transaction is started but not completed before a read transaction is started, the read transaction will not contain the new data the right transaction creates. I can confirm this by calling insert(), then within its promise.then() call a getAll(), the getAll() results do NOT contain the newly inserted data. See http://stackoverflow.com/questions/16424897/onsuccess-and-oncomplete-call-back-is-not-working-for-indexeddb-add-transaction

My work around was to pass an option to insert(), ie insert({my_object}, true), where true will resolve the $q within this.transaction.complete instead of just within req.onsuccess():

"insert": function(data, oncomplete){
    var d = $q.defer();
    return this.internalObjectStore(this.storeName, READWRITE).then(function(store){
        var req;
        if (angular.isArray(data)) {
            data.forEach(function(item){
                req = store.add(item);
                req.onsuccess = req.onerror = function(e) {
                    $rootScope.$apply(function(){
                        d.resolve(e.target.result);
                    });
                };
            });
        } else {
            req = store.add(data);
            req.onsuccess = req.onerror = function(e) {

                if(oncomplete === true){
                    this.transaction.oncomplete = function(){
                        console.log('Insert transaction completed.');

                        $rootScope.$apply(function(){
                            d.resolve(e.target.result);
                        });
                    };
                }
                else{
                    $rootScope.$apply(function(){
                        d.resolve(e.target.result);
                    });
                }
            };
        }
        return d.promise;
    });
},

The only other way to make this work is to use the same transaction call that is suggested via the stackoverflow link above.

Either way the update and delete calls should probably have something similar, or these methods should by default always resolve their promises in their respective oncompletes instead of just onsuccess. Please let me know if there is another way to solve this. Thanks

The current status and the future of this project?

The README.md file states that

> Important note: that this software is in alpha state

But seeing that the last change to src code was some 4 months ago and that the owner of the repo @webcss 's last public github activity was a month ago, it seems like this project is not being actively developed.

Can you (@webcss) please tell me the current state of this project's development, the list of features that are not added yet, and any plans that you have for the future of this project?

I think that this should be added to README.md, since any person who wants to use this should be informed about the status of the project and its future so that they can make an informed decision.

Database is not creating

This code is not working on angular 1.5v, no debug mode ?, no error log ?

$indexedDBProvider.connection('localDatabasex');.upgradeDatabase(1, function (event, db, tx) {
   console.log(db);
   //Create Objects -- CityMaster
   var objStore = db.createObjectStore('citymaster', { keyPath: 'ssn' });
   objStore.createIndex('cityid', 'int', { unique: false });
   objStore.createIndex('cityname', 'cityname', { unique: false });
   objStore.createIndex('statename', 'statename', { unique: false });
   objStore.createIndex('customcity', 'customcity', { unique: false });
   objStore.createIndex('Whenupdate', 'Whenupdate', { unique: false });
   objStore.createIndex('recentcity', 'recentcity', { unique: false });

});

Bower package is broken

Another package currently uses the name angular-indexedDB, and accordingly, this package cannot be installed from the Bower registry.

$ bower install angular-indexedDB --save
    bower not-cached    git://github.com/gdi2290/angular-indexedDB.git#*
    bower resolve       git://github.com/gdi2290/angular-indexedDB.git#*
    bower not-cached    git://github.com/gdi2290/angular-indexedDB.git#~0.0.1
    bower resolve       git://github.com/gdi2290/angular-indexedDB.git#~0.0.1
    bower download      https://github.com/gdi2290/angular-indexedDB/archive/v0.0.1.tar.gz
    bower download      https://github.com/gdi2290/angular-indexedDB/archive/v0.0.1.tar.gz
    bower extract       angular-indexedDB#* archive.tar.gz
    bower extract       angular-indexedDB#~0.0.1 archive.tar.gz
    bower resolved      git://github.com/gdi2290/angular-indexedDB.git#0.0.1
    bower resolved      git://github.com/gdi2290/angular-indexedDB.git#0.0.1
    bower install       angular-indexedDB#0.0.1

    angular-indexedDB#0.0.1 bower_components/angular-indexedDB

Code mistakes ?

Hello, as I'm new to javascript and angular, I learn it by reading your code and I wonder if what I see as mistakes is real ones or just the conséquence of my ignorance :

  • line 210, shouldn't it be "req = store.add(item)" ?
  • lacking "return req" in line 315 (find) and line 377 (each) ?

Thank your very much for giving access to your code ! It's a great help to see real programming !

Unit Tests

This project could use some unit tests.

$asc() and $desc() use deprecated constants

As per this Mozilla bug, PREV, NEXT, PREVUNIQUE and NEXTUNIQUE are deprecated. This can cause issues in Google Chrome due to the way Chrome implements the IndexedDB specification:

Be careful in Chrome as it still implements the old specification along the new one. Similarly it still has the prefixed webkitIndexedDB property even if the unprefixed indexedDB is present.

Use of $rootScope.$apply

Hi,

I wanted to understand the use of $rootScope.$apply. This lines are causing an error in my app.
Error: $digest / $apply already in progress

I know this is occuring because there is a $digest / $apply is running already in my application when the code from the angular-indexedDb is running.

However when i comment these lines in the entire file. My app works fine. Any help or information regarding the same would be greatly appreciated.

Best Regards,
TNTV33

Possible bugs on "each" feature

I believe "each" has some bugs

  1. I get errors like "object is not a function" because of line 449 callback(e.target.result);
  2. No results because of line 446 if(!e.target.result){

Maybe

...
req.onsuccess = req.onerror = function(e) {
    $rootScope.$apply(function(){
        if(!e.target.result){
            d.resolve(e.target.result);
        }
        callback(e.target.result);
    });
};
...

should be something like

..
req.onsuccess = req.onerror = function(e) {
    $rootScope.$apply(function(){
        if(e.target.result){
            d.resolve(e.target.result);
        }
    });
};
...

with my suggestion things seem to work better but I have no idea is it correct.

What I have is something like

Setup:

var store = db.createObjectStore('fooBar', {keyPath: 'fooBarId', autoIncrement:true});
store.createIndex('keyIndex', ['foo','bar'], {unique:false});

Query:

var store = $indexedDB.objectStore('fooBar');

var key = [ fooValue, barValue ];

var query = $indexedDB.queryBuilder()
                .$index('keyIndex')
                .$eq(key)
                .compile();

return store.each(query).then(function(cursor) {
    if (cursor.value) {
        return cursor.value;
    }
});

works on chrome but not firefox

chrome version 33.0.1750.117
firefox version 24.2.0
Anyone seen this behavior? Any thoughts on what to look at to find out why it isn't working?

Ted

no method '$index'

I'm liking that lib so far, but I have troubles with the queryBuilder.
I'm using something like:
var myQuery = $indexedDB.queryBuilder.$index('class_idx').$eq(class_id_).compile;
But in the console, I have a big error:
TypeError: Object function () {
return new QueryBuilder();
} has no method '$index'
I can use "getAll()" and such, but not that $index, to then loop with "each()" on the found results...
Any idea?
Thanks.

QueryBuilder direction

Currently QueryBuilder has $asc() and $desc() which set the query order (cursor transversal direction) but there is no inteface to set the direction (results order).

QueryBuilder using the same defaultQueryOptions instance every time.

indexeddb.js line 94.

var defaultQueryOptions = {
    useIndex: undefined,
    keyRange: null,
    direction: NEXT
};

This is used everytime even when instantiating a new QueryBuilder object at indexeddb.js line 432.

this.result = defaultQueryOptions;

So with two QueryBuilders, they will both share the same instance of this.result. Suggest wrapping defaultQueryOptions in a function that returns a new instance of that object.

Bower.json

Hey.
Great job... it works fine thanks a lot.

But using Bower, why we can't add such a line "angular-indexDB": "=X.y.zz" into bower.json compared to other libs like :
"angular": "=1.3.6",
"angular-animate": "=1.3.6",
"angular-sanitize": "=1.3.6",
"angular-touch": "=1.3.6",

?
Thanks for your answer.
regards
R.

How to create index on array element in indexeddb

I have an object.

var _data = {
teacher : {
name : "Mack",
subject : "Maths"
},
Student : [{
stud_name : "Alex",
stud_id : 1
},{
stud_name : "Jack",
stud_id : 2
},{
stud_name : "Mark",
stud_id : 3
}]
};

I want to create index on array element of object.
i.e, I want to create an index on stud_name. Is it possible to create such type of index in indexeddb?

Query compilation error

In my Chrome I've got an error with this code var myQuery = $indexedDB.queryBuilder().$index('age_idx').$gt(40).$asc.compile();
but without .$asc snipped it works ok. Where I get to know more knowledge about correct query composing?

Errors are not caught in many places

Throughout the library, there are several instances of req.onsuccess = req.onerror, which results in promises resolving when they should have been rejected.

Additionally, many methods within the IndexedDB API can potentially raise DOMExceptions, which are not caught at all by angular-indexedDB. These exceptions can be particularly problematic, because they are often raised within then() blocks inside the library (which makes them impossible to catch from the outside).

Move all code inside the module definition

I know this project has been taken over by @bramski (https://github.com/bramski/angular-indexedDB), but GitHub won't let me post an issue on that fork, so I'm posting it here instead.

Currently, the following lines are outside of the angular.module definition, which means they run immediately when the file is loaded, rather than waiting for angular.bootstrap to occur.

var IDBKeyRange, indexedDB,
  __slice = [].slice;

indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;

IDBKeyRange = window.IDBKeyRange || window.mozIDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;

The problem is that if I'm running in a browser that doesn't natively support IndexedDB, and I'm loading a polyfill instead, then the above code will only work if the polyfill is loaded before the angular-indexed-db.js file. But if the polyfill is being loaded dynamically (say, as an Angular module, a Require.js module, a Browserify package, or a Cordova plugin), then the polyfill won't load in time, and Angular-IndexedDB won't work.

To fix this problem, the four lines of code shown above just need to be moved inside of the angular.module definition. That way, they won't run until all dynamically-loaded scripts are finished loading and angular.bootstrap is called.

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.