dexie / Dexie.js

A Minimalistic Wrapper for IndexedDB
https://dexie.org
Apache License 2.0
11.49k stars 642 forks source link

How to check for browsers unsupported by dexie? #234

Closed matusferko closed 8 years ago

matusferko commented 8 years ago

Hi, How dexie behaves when browser doesn't support indexdb? Is there general approach I could use to check if i can use dexie in current environment?

aaron-schmidt commented 8 years ago

A bit long winded but I use something similar to the following. It uses jQuery Deferred but any other deferred implementation should work.

var _idb; // Local var to hold Dexie instance

function openIndexedDB() {
    var deferred = $.Deferred();
    var success = false;

    var openIndexedDBFailure = function(module, error) {
        console.log("Opening IndexedDB failed during " + module + " with: " + error);
        _idb = false;
        deferred.reject();
    };

    // Ensure 'Dexie' object exists
    if (typeof Dexie === 'undefined') {
        return openIndexedDBFailure('Dexie', "Dexie object is undefined");
    }

    // Define structure
    _idb = new Dexie('dbname');
    _idb.version(1).stores({storename: 'key1, key2, etc'});

    // Sample data for testing
    var store = {key1: 'test', key2: 'test', data: 1, etc};

    // Attempt to open IndexedDB
    _idb.open()
        .then(function() {
            // Attempt to put data into IndexedDB
            _idb.storename.put(store)
                .then(function() {
                    // Attempt to get data from IndexedDB
                    _idb.storename.get(key)
                        .then(function() {
                            // Attempt to delete data from IndexedDB
                            _idb.storename.delete(key)
                                .then(function() {
                                    // Success
                                    success = true;
                                    deferred.resolve();
                                })
                                .catch(function(error) {
                                    openIndexedDBFailure('delete', error);
                                });
                        })
                        .catch(function(error) {
                            openIndexedDBFailure('get', error);
                        });
                })
                .catch(function(error) {
                    openIndexedDBFailure('put', error);
                });
        })
        .catch(function(error) {
            openIndexedDBFailure('open', error);
        });

    // Fail if IndexedDB doesn't respond within 9 seconds
    window.setTimeout(function() {
        if (!success) {
            openIndexedDBFailure('timeout', "No response after 9 seconds");
        }
    }, 9000);

    return deferred;
}

Usage:

openIndexedDB.done(function() {
    console.log("Success: Browser supports IndexedDB");
}).fail(function() {
    console.log("Failure: Browser does not support IndexedDB");
});

Later, you can simply falsey check the _idb var before working with it.

matusferko commented 8 years ago

uau, I expected it's more simple than that. I wouldn't wait 9 seconds for db to response though :)

So it looks like even if the browser doesn't support indexedDb it's save to call dexie api.

I was wondering if this is safe to call or should it by in try {} catch{} : _idb = new Dexie('dbname'); _idb.version(1).stores({storename: 'key1, key2, etc'});

dfahlander commented 8 years ago

Dexie users promises so you can't do try catch but instead catch a Dexie open operation for example.

I would just catch the call to db.open() and if that fails with 'MissingApiError', assume there's no indexedDB.

Look at this jsfiddle who does that.

var db = new Dexie ('appDB');
db.version (...).stores (...)
db.open()
    .catch ('MissingApiError', function (e) {
        // Show message to user that indexedDB is missing 
    }).catch (function (e) {
        // Show e.message to user 
    });
dfahlander commented 8 years ago

Closing