Allow v-table :model to render re-frame subscriptions as well as reagent atoms?
ryrobes opened this issue · 5 comments
Hi - I am unable to get v-table / simple-v-table to accept anything other than a "hard" reagent atom. Passing my re-frame subscription gets interpreted as a regular vector of maps, and putting my subscription result into an atom (while passing validation) renders as an empty vector would. Is there a workaround - maybe I am missing something?
Anyways - love the library! Cheers.
Thanks for the report @ryrobes 😄
By a
"hard" reagent atom
are you referring to reagent.ratom/atom
and by
putting my subscription result into an atom
are you referring to a cljs.core/atom
?
If that is the case then I can confirm only the reagent.ratom/atom
(usually abbreviated as r/atom
) will work for :model
for v-table or any other re-com component.
This is because reagent views need to keep track of derefs. There is some information available in the reagent documentation.
We successfully use re-frame subscriptions and r/atom
s daily with v-table in our commercial applications so I don't think there is a bug with the code.
However I think there are at least two issues we do need to fix:
-
Documentation bug. The current v-table documentation at https://re-com.day8.com.au/#/v-table only mentions
atom containing vec of maps
and nothing aboutr/atom
which is certainly confusing and I imagine what misled you ? Other components such as checkbox mentionr/atom
although that is still quite subtle. Isr/atom
enough to point library users in the right direction ? -
Validation bug. As you've rightly pointed out if
r/atom
is what is required andcljs.core/atom
cannot work as expected thencljs.core/atom
should fail validation, and it currently passes validation.
Those two issues together are a pretty brutal combination. We'd never have noticed this ourselves since it is more of a documentation issue so thank you for raising this issue otherwise I imagine quite a few users would continue struggling with this!
Appreciate the thoughtful response - yes, I meant an actual reagent atom (I think that your examples make that pretty clear actually), i.e. Forgive my lack of experience here - but generally in re-frame I will either deref the subscription in a let (probably a terrible practice), or do it inline, but am unable to get either of these methods to render.
i.e. (let [my-data @(rf/subscribe [::subs/my-data-fetching-sub])
and then :model my-data
(which fails validation since it looks like a regular vector of maps), or even :model @(rf/subscribe [::subs/my-data-fetching-sub])
to be pedantic - or passing validation with something like :model (r/atom my-data)
which passes, but doesn't properly render (and would possibly be hacky even if it did). In the rest of my code this generally works fine. I'm possibly missing something basic here, so apologies. :)
What is the pattern you use in this case? Again, appreciate it.
Update: I realize that I didn't make my request very succinctly before - can you please provide a small snippet or example of using a re-frame subscription to drive the :model (like you said happens in your other commercial projects)?
We do stuff like:
(defn foo-table
(let [a @(rf/subscribe [::a])
b (map-indexed ... a)]
[rc/simple-v-table
:model (-> b vec r/atom)]))
Thanks. I now realize now that my problem was an incorrect columns definition and not the sub data itself (i.e. it existed, passed validation, but was wrong). [Forehead Smack]
:model (reagent/atom my-sub-data) ; already a vector of uniform maps
Works fine.
Maybe make that key optional and if it doesn't exist generate a simple one, a la
:columns (into []
(for [k (keys (get my-sub-data 0))]
{:id k :header-label (str k) :row-label-fn k :width 150 :height 70}))
Regardless, closing this. Cheers.