Thursday, March 1, 2012

Dart IndexedDB: FIXME

‹prev | My Chain | next›

Thanks to my work on the varying the data sync method in Hipster MVC, I have a pretty good handle on how to do localStorage() in Dart. I do not have much experience with the other HTML5-ish client store, IndexedDB, so today I set out to learn it and how to use it in Dart. What could go wrong?

So I begin with the simplest use-case I can find in the MDN documentation—opening a request:
#import('dart:html');

main() {
  var request = window.webkitIndexedDB.open('asdf');
  print(request);
}
Loading this up in Dartium, I find:
Exception: NoSuchMethodException : method not found: 'get:webkitIndexedDB'
Receiver: Instance of 'WindowWrappingImplementation'
Arguments: []
Stack Trace:  0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:669 col:3
 1. Function: '::main' url: 'file:///home/cstrom/repos/dart-book/book/includes/client_storage/indexeddb/main.dart' line:4 col:39
Greeeeeat.

If it is not working in dart:html, perhaps the lower-level dart:dom has a working implementation:
#import('dart:dom');

main() {
  var request = window.webkitIndexedDB.open('asdf');
  print(request);
}
Checking the console, I now see:
Instance of 'IDBRequestImplementation'
So that's progress.

The next thing to do with IndexedDB is add event listeners. Since this is dart:dom instead of dart:html, the API omits the now familiar on getter. Instead, I invoke addEventListener directly on the request object:
  var request = window.webkitIndexedDB.open('asdf');

  request.
    addEventListener('error', (event) {
      print("Whoa! Something bad happened: ${event}");
    });

  request.
    addEventListener('success', (event) {
      print("Niiice! Something good happened: ${event}");
    });
Loading this in Dartium, I see:
Niiice! Something good happened: Instance of 'EventImplementation'
Hrm... I am not quite sure why I am getting a success event, but I suppose it beats the alternative.

Ah, it seems that success means that I have access to do IndexedDB stuff. So I'm ready to try grabbing a DB object out of the event target (which is the request):
  request.
    addEventListener('success', (event) {
      print("Niiice! Something good happened: ${event.target}");

      db = event.target.result;
      print("the db is: ${db}");
    });
Only this fails when I try to access the result property:
Exception: NotImplementedException
Stack Trace:  0. Function: 'IDBRequestImplementation.get:result' url: '/mnt/data/b/build/slave/dartium-lucid64-inc/build/src/out/Release/obj/gen/webkit/bindings/dart/generated/dart/IDBRequestImplementation.dart' line:18 col:3
 1. Function: '::function' url: 'file:///home/cstrom/repos/dart-book/book/includes/client_storage/indexeddb/main.dart' line:17 col:31
That is a not-implemented exception, not a no-such-method exception. In other words, it is supposed to be implemented, but seemingly is not.

I give this a try in type checked mode and find:
Exception: '/mnt/data/b/build/slave/dartium-lucid64-inc/build/src/out/Release/obj/gen/webkit/bindings/dart/generated/dart/EventImplementation.dart': Failed type check: line 36 pos 3: type 'IDBRequestImplementation' is not assignable to type 'EventTarget' of 'function result'.
Stack Trace:  0. Function: 'EventImplementation.get:target' url: '/mnt/data/b/build/slave/dartium-lucid64-inc/build/src/out/Release/obj/gen/webkit/bindings/dart/generated/dart/EventImplementation.dart' line:36 col:3
 1. Function: '::function' url: 'file:///home/cstrom/repos/dart-book/book/includes/client_storage/indexeddb/main.dart' line:9 col:61
Hrm... that failed type check starts in my code, but actually generated in Dart itself. At first glance, it seems that IDBRequestImplementation might not implement EventTarget. Regardless, that is not much help in explaining why this is not working for my in non-checked mode.

I look through the generated source code, but it looks to be a lot of native code. Ugh. Seemingly at a dead end, I call it a night here. I will recompile the latest version of Dartium to see if that helps. But at this point, it seems that the client storage chapter in Dart for Hipsters is destined to be quite short.

Update: I eventually found Seth Ladd's post on Dart IndexDB. Unfortunately, I ended up with the same results.


Day #312

1 comment:

  1. Hi Chris,

    I managed to get IndexedDB working, check out this code: https://github.com/sethladd/lawndart/blob/master/lib/indexeddb-adapter.dart

    Caveat one: I needed to JSON encode objects before I put them into the DB. There's an open bug for this.

    Granted, there are quite a few bugs left, but I was able to insert, delete, query by key, etc.

    I haven't tried querying by index, yet, though.

    ReplyDelete