Tuesday, December 4, 2012

Dart localStorage is a HashMap

‹prev | My Chain | next›

As I prep for an updated Dart for Hipsters, I find myself in a rather unique situation with my sample application. I wrote Dart Comics as a way of exploring Dart myself and for the reader. As such, I have a bunch of different branches that correspond to different junctures in the book. Each of those branches build on each other, making for a nice narrative.

A nice narrative, but what happens when I go back to the your_first_dart_app branch to update it for recent Dart? Then I have to somehow get all of my other branches—that used to be based on the your_first_dart_app branch—converted over to use the updated branch as the base. This seems like a use-case for git-rebase. Yesterday, I had worked my way through the mvc branch, so tonight, I switch to the mvc-sync branch and rebase it onto the just fixed mvc branch:
➜  dart-comics git:(mvc) git co mvc-sync
Switched to branch 'mvc-sync'
➜  dart-comics git:(mvc-sync) ✗ git rebase mvc
First, rewinding head to replay your work on top of it...
Applying: Swap out the Ajax store for a local store equivalent
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging public/scripts/HipsterModel.dart
CONFLICT (content): Merge conflict in public/scripts/HipsterModel.dart
Auto-merging public/scripts/HipsterCollection.dart
CONFLICT (content): Merge conflict in public/scripts/HipsterCollection.dart
Failed to merge in the changes.
Patch failed at 0001 Swap out the Ajax store for a local store equivalent
...
And then I fix a lot of merge conflicts. Once that is done, I tag the old mvc-sync head and do my favorite thing with git, force the update:
➜  dart-comics git:(mvc-sync) gp origin mvc-sync
To git@github.com:eee-c/dart-comics.git
 ! [rejected]        mvc-sync -> mvc-sync (non-fast-forward)
error: failed to push some refs to 'git@github.com:eee-c/dart-comics.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
➜  dart-comics git:(mvc-sync) gp origin mvc-sync --force
Counting objects: 691, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (669/669), done.
Writing objects: 100% (681/681), 478.37 KiB, done.
Total 681 (delta 257), reused 0 (delta 0)
To git@github.com:eee-c/dart-comics.git
 + 3acb937...733fbf0 mvc-sync -> mvc-sync (forced update)
Good times. I am not done with this branch yet as a few thing slipped through. So I spend some time with the dart_analyzer fixing said things up.

Most of the the problems that dart_analyzer points out are the same-old M1 release updates. But I happen across a localStorage issue that was also pointed out in the errata for Dart for Hipsters. The whole point of the mvc-sync branch was to experiment with varying behavior in Dart. In this branch, I dynamically swapped out the normal REST-like syncing behavior for a localStorage version:
main() {
  HipsterSync.sync = localSync;
  // ...
}

localSync(method, model, [options]) {
  print("[local_sync] $method");

  if (method == 'get') {
    var json =  window.localStorage.getItem(model.url),
      data = (json == null) ? {} : JSON.parse(json);

    if (options is Map && options.containsKey('onLoad')) {
      options['onLoad'](data.getValues());
    }
  }
}
The problem is that Dart no longer follows the JavaScript API for localStorage. Instead of getItem(), Dart treats localStorage as a HashMap, meaning that I can use square brackets to access values:
localSync(method, model, {options}) {
  print("[local_sync] $method");

  if (method == 'get') {
    var json =  window.localStorage[model.url],
      data = (json == null) ? {} : JSON.parse(json);
    // ...
  }
}
I really love little wins like that. Can't wait to share them in the book!


Day #589

No comments:

Post a Comment