On Thursday, March 26, 2015 at 2:08:23 AM UTC+11, Jamie Orchard-Hays wrote:
> In Om, I didn't have to think about how to find the data in app-db to update 
> as Om has cursors. In the cursorless world of re-frame, I am wondering what 
> are favorite strategies for updating data deep inside a decently rich app-db 
> tree.
> 
> ie, say I want to update a field that is in a map that is in a list in 
> app-db. I want to update the :name value in one of the maps in :some-list:
> 
> (def app-db (atom
>   {:some-list
>     [{:id "asdfadfa" :name "Foo Bar" ...}
>      {:id "gfdsalkjc" :name "Boo Baz" ...}
>      ....]}))
> 
> This isn't so difficult to approach, but what about a field in a map in a 
> list in a map in a list... You get the idea.
> 


Tim Peters guides us in this area by recommending:  "Flat is better than 
nested". 
https://www.python.org/dev/peps/pep-0020/

But that isn't always possible, I know, so to answer your question instead of 
providing gratuitous quotations ... 

As much as possible, I try to conceptualise "app-db" to be a database. That's 
the reason for that "db" in the name. 

And, if you wanted to "update" a database, you need:
   - the unique key of the thing to be updated
   - the name of the table (collection).

Generally "path middleware" nicely handles the "name of the table" part of this 
pair.  It gets your handler to the "root" of the data structure (table? 
collection?). 

In the situation you are describing, the "unique key" bit is some sort of 
"path" into a data structure. There are layers of vectors and maps to traverse, 
even if middleware gets you to the base of this data structure you want to 
update. 

In such a case, you'll have to "build the unique key" as you descend. A 
read-only cursor-like process. 

So, let's imagine you represent your path as a vector (of keys or indexes), 
then in each level you would pass down this path vector, conj-ed with a new 
part of the id, incrementally building the unique key as you descend, and 
passing it down.

Then, at the leaves, when you "dispatch", you can include the path vector in 
the event payload.  The handler then has the information it needs to perform 
the update. 

This deep-tree situation is not a common usecase for me, but if you ran into 
this situation a lot, then I'd think about adapting the reagent cursors for the 
job.

In summary:  when you dispatch, pass through the "unique key" (path), of the 
thing you want updated.   Your handler may additionally have "path middleware" 
on it, which resolves the “name of the table” part of any update.  So you get 
the job done via that combination. 

A super simple version of this, can be seen here:
https://github.com/Day8/re-frame/blob/46b8848f3bab432832a4517f0cccf36cb4197f65/examples/todomvc/src/todomvc/handlers.cljs#L54-L58

"todo-ware" contains path middleware which gets the handler directly to the 
"todos table" (see the parameter "todos"), and the "id" in the event is the 
unique key required for the update. In your case, you'd just have a more 
complicated "id" (it's a vector created in a read-only cursor-like fashion).  

I worry that I've simply told you what you already know here.


--
Mike


-- 
Note that posts from new members are moderated - please be patient with your 
first post.
--- 
You received this message because you are subscribed to the Google Groups 
"ClojureScript" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/clojurescript.

Reply via email to