I'm trying to understand the normalization, identity and querying concepts in Om Next. Every time I think I have it, I run into a new situation that seems to baffle me.
I have a remote that returns the following data:
{:users [
{:id 1,
:email "[email protected]",
:role 1},
{:id 3,
:email "[email protected]",
:role 1},
{:id 4,
:email "[email protected]",
:role 1},
{:id 6,
:email "[email protected]",
:role 1}}]
:roles [
{:id 1, :name "admin"}]}
I've structured my components like this:
(defui Root
static om/IQuery
(query [this]
`[{:users ~(om/get-query User)}
{:roles ~(om/get-query Role)}]))
(defui Role
static om/Ident
(ident [this {:keys [id]}]
[:role/by-id id])
static om/IQuery
(query [this]
[:id :name]))
(defui User
static om/Ident
(ident [this {:keys [id]}]
[:user/by-id id])
static om/IQuery
(query [this]
[:id :email :role]))
This results in the reconciler normalizing my data like this:
{:users
[[:user/by-id 1] [:user/by-id 3] [:user/by-id 4] [:user/by-id 6]],
:roles [[:role/by-id 1]],
:user/by-id
{1
{:id 1,
:email "[email protected]",
:role 1},
3
{:id 3,
:email "[email protected]",
:role 1},
4
{:id 4,
:email "[email protected]",
:role 1},
6
{:id 6,
:email "[email protected]",
:role 1}},
:role/by-id {1 {:id 1, :name "admin"}}}
Now, as to my question. I'd like to access a user's role's name inside the component. I could simply do something like (get-in @app-state [:role/by-id role :name])
within the render function of the User component, but that doesn't seem like the idiomatic thing to do.
The Om Next document on "Thinking with links" seems to mention my solution: idents. I've tried to use this within the User query (like [:id :email [:role/by-id 1]]
) and that works! However, I can't seem to insert the actual role id into the ident! I've tried very complicated things with query parameters, inserting it into the indent like that, but it all seems horribly contrived.
This seems like an incredibly common situation for which a decent solution should exist, but I can't seem to get it!
*EDIT Added the Root component
Your query syntax for
User
ought to be something like this:Then the table state for a user might be:
It would help if you showed your
defui
s in the question, especially forRoot
. One thing with Om.Next is that all the joins have to be done on theRoot
component in order to get the app state properly normalized.