/ #cloud #dotcloud 

OpaDo Data Storage

OpaDo (a port of the TodoMVC app to Opa) now persists todo items to the Opa database. The new version is up on dotcloud, http://opado-tristan.sloughter.dotcloud.com/

I’ve added a _todoitem type which stores the item’s value and two other attributes we won’t use until the next post when we have user accounts for their own _todoitem stores.

type todo_item = { user_id : string
; value : string
; created_at : string
}

To tell Opa where to store the records we’ll create, we provide a path to the Opa db function and set its type. For our todo items we use a stringmap since currently the id’s are randomly generated strings (I know, I know, but its just an example!). We can then reference a record in the database with the path /todo_item[some_id_string].
db /todo_items : stringmap(todo_item)

Now we can insert _todoitem’s to this db path as so:
/todo_items[id] <- { value=x user_id=”” created_at=”” }

For now _userid and _createdat are empty, but I’ll be updating that when I add user accounts.

Since we are storing each item, we need to populate the list on page load with whats already stored:

add_todos() =
items = /todo_items
StringMap.iter((x, y -> add_todo_to_page(x, y.value)), items)

The first line of the function sets the variable items to all the _todoitem records in the database. We use StringMap.iter to take each _todoitem and add it to the page. The first argument to the anonymous function is the id the item is stored in the database with (the id we will use in the HTML as well) and the second is the actual _todoitem, so we take its value field and pass that to the _add_todo_topage function along with the id.

To have the _addtodos function when the list element is ready we add an _onready attribute that will call add_todos:

<ul id=#todolist onready={ -> add_todos() } ></ul>

Lastly, we want to be able to delete a _todoitem from the database:
remove_item(id: string) =
do Dom.remove(Dom.select_parent_one(#{id}))
do Db.remove(@/todo_items[id])
update_counts()

remove_all_done() =
Dom.iter(x -> remove_item(Dom.get_id(x)), Dom.select_class(“done”))


The main piece to notice here is [email protected]/todoitems[id] in Db.remove(). The @ is saying that we are passing the path itself to remove() and not the value at that path.

Nice and easy! No database to setup or deploy, just Opa. Next time we’ll add user accounts, so we don’t have to all share the same todo list.