Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"undefined is not a function (evaluating 'a.addEventListener(b,c)')","name":"TypeError"} #187

Open
ls-simon-he opened this issue Dec 13, 2017 · 3 comments

Comments

@ls-simon-he
Copy link

ls-simon-he commented Dec 13, 2017

Issue:

Got an exception when tried to add listener to db.
"undefined is not a function (evaluating 'a.addEventListener(b,c)')","name":"TypeError"}

How to reproduce on Safari of iOS 8/9:

var server;
db.open({
    server: 'my-app',
    version: 1,
    schema: {
        people: {
            key: {keyPath: 'id', autoIncrement: true},
            // Optionally add indexes
            indexes: {
                firstName: {},
                answer: {unique: true}
            }
        }
    }
}).then(function (s) {
    server = s;
   // The line will throw error
    server.addEventListener('versionchange', function(e) {
    });
});
@aaronpowell
Copy link
Owner

I didn't think indexedDB was really classed as supported until iOS 10. According to caniuse.com indexeddb on 8/9 was marked as very unstable.

That said, looking at your sample code above the type of s in the resolved promise isn't an IndexedDB type, it's the Server type used internally by db.js, which doesn't expose that function, hence the error you're receiving.

Instead you need to call the getIndexedDB function to return the raw IndexedDB object.

That said, your code wouldn't work anyway as the promise will be resolved after the versionchange event has fired, it's captured here: https://github.com/aaronpowell/db.js/blob/master/src/db.js#L780 and I don't think there's anywhere I expose a hook into that event.

@ls-simon-he
Copy link
Author

@aaronmccall Thanks for your clarifying. By tracing the code, I found the server.addEventListener() actually just forwards the event binding to the raw IndexedDB object at: https://github.com/aaronpowell/db.js/blob/master/src/db.js#L620
And just the line caused the exception: the raw IndexedDB doesn't support the method addEventListener()! Then I changed to db['on' + eventName] = handler;, it works.
So here is the fix:

        this.addEventListener = function (eventName, handler) {
            if (!serverEvents.includes(eventName)) {
                throw new Error('Unrecognized event type ' + eventName);
            }
           const errorHandler =  function (e) {
                    e.preventDefault(); // Needed by Firefox to prevent hard abort with ConstraintError
                    handler(e);
            };
            const h = eventName === 'error' ? errorHandler : handler;
             if (db.addEventListner) {
                 db.addEventListener(eventName, h);
             } else {
                 db['on' + eventName] = h;
             }
        };

        this.removeEventListener = function (eventName, handler) {
            if (!serverEvents.includes(eventName)) {
                throw new Error('Unrecognized event type ' + eventName);
            }
            if (db.removeEventListener) {
                 db.removeEventListener(eventName, handler);
             } else {
                 db['on' + eventName] = null;
             }
        };

@aaronpowell
Copy link
Owner

Oh, I didn't know I exposed that functionality. Well there you go ey!

TBH I'm hesitant to add this change without understanding the underlying cause properly. I'd be quite shocked that a browser didn't support addEventListener on the indexedDB object needs to inherit from EventTarget, which all implementations did.

Also using the on<eventName> approach is not that great, you can only assign a single event listener to that event.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants