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 "foo@example.com",
:role 1},
{:id 3,
:email "bar@floyhamilton.nl",
:role 1},
{:id 4,
:email "baz@example.com",
:role 1},
{:id 6,
:email "nom@example.com",
: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 "foo@example.com",
:role 1},
3
{:id 3,
:email "bar@floyhamilton.nl",
:role 1},
4
{:id 4,
:email "baz@example.com",
:role 1},
6
{:id 6,
:email "nom@example.com",
: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