Permalink
Browse files

First local storage impl

  • Loading branch information...
1 parent 22f5854 commit dc766a19e601d53d66cca444cc8ed5778db0c0c7 @MathieuLorber committed Oct 21, 2012
@@ -2,6 +2,7 @@ part of todomvc;
class TodoApp {
List<TodoElement> todoElements = new List();
@sethladd
sethladd Oct 23, 2012 Collaborator

add new List()

@MathieuLorber
MathieuLorber Oct 24, 2012 Owner

I think I haven't understand this one...

@MathieuLorber
MathieuLorber Oct 24, 2012 Owner

Is it about the instantiation of lists with [] as suggested by @jacob314 ?

@sethladd
sethladd Oct 25, 2012 Collaborator

Oh, oops, html escape didn't work.

Change to:

List<TodoElement> todoElements = new List<TodoElement>();
@MathieuLorber
MathieuLorber Oct 25, 2012 Owner

I could have understood... @jacob314 suggested to use []. As a java dev, I prefer new List(), but [] is commited for the moment....

So, which one ?

@sethladd
sethladd Oct 25, 2012 Collaborator

I personally like the use of

new List<TotoElement>();
+
Element todoListElement = query('#todo-list');
Element mainElement = query('#main');
InputElement checkAllCheckboxElement = query('#toggle-all');
@@ -13,15 +14,39 @@ class TodoApp {
Element showCompletedElement = query('#filters a[href="#/completed"]');
TodoApp() {
+ initLocalStorage();
+ initElementEventListeners();
+
+ window.on.hashChange.add((e) => updateFilter());
+
+ updateFooterDisplay();
+ }
+
+ void initLocalStorage() {
+ String jsonList = window.localStorage["todos-vanilladart"];
+ if(jsonList != null) {
+ try {
+ List<Map> todos = JSON.parse(jsonList);
+ todos.forEach((Map todo) {
@sethladd
sethladd Oct 23, 2012 Collaborator

Try for (Map todo in todos) instead

@MathieuLorber
MathieuLorber Oct 24, 2012 Owner

Ok, it's a simpler syntax, I changed all of them

+ addTodo(new Todo(todo['id'], todo['title'], Boolean.parse(todo['completed'])));
@sethladd
sethladd Oct 23, 2012 Collaborator

Create a named constructor on Todo like:

Todo.fromJson(String json) {
  id = json['id'];
  title = json['title'];
}

and then replace the above with addTodo(new Todo.fromJson(todo))

+ });
+ } catch (e) {
+ window.console.log("Could not load todos form local storage.");
+ }
+ }
+ }
+
+ void initElementEventListeners() {
InputElement newTodoElement = query('#new-todo');
newTodoElement.on.keyPress.add((KeyboardEvent e) {
if(e.keyIdentifier == KeyName.ENTER) {
String title = newTodoElement.value.trim();
if(title != '') {
- addTodo(title);
+ addTodo(new Todo(UUID.get(), title));
newTodoElement.value = '';
updateFooterDisplay();
+ save();
}
}
});
@@ -34,6 +59,7 @@ class TodoApp {
}
});
updateCounts();
+ save();
});
clearCompletedElement.on.click.add((MouseEvent e) {
@@ -47,16 +73,11 @@ class TodoApp {
});
todoElements = newList;
updateFooterDisplay();
+ save();
});
-
- window.on.hashChange.add((e) => updateFilter());
-
- updateFooterDisplay();
}
- void addTodo(String title, [bool completed = false]) {
- Todo todo = new Todo(title, completed);
-
+ void addTodo(Todo todo) {
TodoElement todoElement = new TodoElement(this, todo);
todoElements.add(todoElement);
todoListElement.nodes.add(todoElement.createElement());
@@ -146,4 +167,19 @@ class TodoApp {
todoElement.hide();
}
}
+
+ void save() {
+ StringBuffer storage = new StringBuffer('[');
+ todoElements.forEach((TodoElement todoElement) {
@sethladd
sethladd Oct 23, 2012 Collaborator

Consider for (TodoElement in todoElements)

+ storage.add(todoElement.todo.toJson());
+ storage.add(',');
+ });
+ String finalJson;
+ if(storage.toString() != '[') {
+ finalJson = '${storage.toString().substring(0, storage.toString().length - 1)}]';
+ } else {
+ finalJson = '[]';
+ }
+ window.localStorage["todos-vanilladart"] = finalJson;
+ }
@sindresorhus
sindresorhus Oct 22, 2012

Why are you not using JSON.stringify() ?

@MathieuLorber
MathieuLorber Oct 22, 2012 Owner

Because it seems i have to use a library to use JSON.stringify on an object ( https://github.com/chrisbu/dartwatch-JsonObject ). It was simpler to write toJson() (and the forEach loop with a call to Todo constructor in initLocalStorage() instead of parse) first. But I can drill down.

@sindresorhus
sindresorhus Oct 22, 2012

I must be misunderstanding?

JSON.stringify({foo:'bar'});
// "{"foo":"bar"}"
@MathieuLorber
MathieuLorber Oct 23, 2012 Owner

It seems I can't use the Dart version of JSON.stringify on an Object which does not extends JsonObject, which is provided by an external lib (for the moment ?). I'm not sure but trying asap

@sethladd
sethladd Oct 23, 2012 Collaborator

JSON.stringify() works just fine on Lists and Maps. For custom objects, you can implement toJson() on TodoElement, which should return Lists and Maps that can be serialized.

For example:

import 'dart:json';

class Custom {
  String name;
  Custom(this.name);

  Map toJson() {
    return {'name': name};
  }
}

void main() {
  var c = new Custom('hello');
  print(JSON.stringify(c));
}
@MathieuLorber
MathieuLorber Oct 24, 2012 Owner

Yes, i misunderstood how to use toJson. Actually my version of yesterday did not work...
Thank you !

}
@@ -28,6 +28,7 @@ class TodoElement {
toggleElement.on.click.add((MouseEvent e) {
toggle();
todoApp.updateCounts();
+ todoApp.save();
});
contentElement.on.doubleClick.add((MouseEvent e) {
element.classes.add('editing');
@@ -41,7 +42,10 @@ class TodoElement {
todoApp.updateFooterDisplay();
}
- element.query('.destroy').on.click.add((MouseEvent e) => removeTodo());
+ element.query('.destroy').on.click.add((MouseEvent e) {
+ removeTodo();
+ todoApp.save();
+ });
void doneEditing() {
todo.title = editElement.value.trim();
@@ -51,6 +55,7 @@ class TodoElement {
} else {
removeTodo();
}
+ todoApp.save();
}
editElement.on.keyPress.add((KeyboardEvent e) {
@@ -1,6 +1,8 @@
library todomvc;
import 'dart:html';
+import 'dart:math';
+import 'dart:json';
part 'TodoElement.dart';
part 'TodoApp.dart';
@@ -10,8 +12,32 @@ void main() {
}
class Todo {
- int id;
+ String id;
String title;
bool completed;
- Todo(this.title, this.completed);
+
+ Todo(String this.id, String this.title, [bool this.completed = false]);
+
+ String toJson() {
+ return '{"id": "$id", "title": "$title", "completed": "$completed"}';
+ }
+}
+
+class UUID {
+ static Random random = new Random();
+
+ static String get() {
+ return "${S4()}${S4()}-${S4()}-${S4()}-${S4()}-${S4()}${S4()}${S4()}";
+ }
+
+ static String S4() {
+ return random.nextInt(65536).toRadixString(16);
+ }
+}
+
+// Dart has no bool.parse for the moment,see http://code.google.com/p/dart/issues/detail?id=2870
+class Boolean {
+ static bool parse(String s) {
@sethladd
sethladd Oct 23, 2012 Collaborator

This is a candidate for a top-level function. No big need to wrap this in a class.

@MathieuLorber
MathieuLorber Oct 24, 2012 Owner

I wish I could remove it ! But I have nothing against the deletion of my "Boolean" class.

@MathieuLorber
MathieuLorber Oct 24, 2012 Owner
  • anyway, I do not need it anymore =)
+ return s == 'true';
+ }
}

2 comments on commit dc766a1

@sethladd
Collaborator

Thanks for the submission!

@MathieuLorber
Owner

Thanks for your time & review ...

Please sign in to comment.