I’m coming back to re-frame after a long absence, so please forgive silly questions! I’m getting a new app off the ground and trying to use re-frame-10x (in an app compiled with Figwheel Main). For some reason it always seem to be one event “behind the times” (so if 3 events have been fired in my app, it only shows the first two). I can force it to update and see the most recent event by hitting the “pop out” button, but I can’t help but think that I’m missing something pretty basic. I’m not really sure where to start with debugging this, and would appreciate some help. Thanks in advance!
In case you don't get an answer here, it might be worthwhile to create a minimal reproducible example and create an issue on GitHub.
Good thought. I’ll do so unless anyone has any immediate thoughts about what might be going on. Thanks!
is there a way to register events locally instead of globally? like private functions
my code looks like this:
;; implementation detail, do not directly use it
(reg-event-db
::start-thinking
(fn [db _]
(assoc-in db [:bot :thinking?] true)))
;; implementation detail, do not directly use it
(reg-event-db
::stop-thinking
(fn [db _]
(assoc-in db [:bot :thinking?] false)))
(reg-event-fx
::think-for-a-while
(fn [_ _]
(let [time-to-wait (utils/generate-sheb-funda-formula)]
{:dispatch [::start-thinking]
:dispatch-later [{:ms time-to-wait
:dispatch [::stop-thinking]}]})))
No. FWIW I just prepend -
to such event IDs to make them different from the others, like ::-start-thinking
.
Alternatively, you can generate keywords dynamically with gensym
and wrap all those calls to reg-event-*
in a single let
that binds those generated keywords to some names that you can use directly. But I would definitely not do such a thing in my code.
For reference, I think I’ve worked this out. I wasn’t actually using any subscriptions in my code (like I said - I’m just getting started with the app). As soon as I actually use a subscription, everything syncs up just fine. I guess that this is a weird edge case (no real app will ever not use any subscriptions) so I won’t worry about it.
Hi all, I’m trying to write a subscription that’s calculated from two other subscriptions, where one of the subs needs to be input to the other sub’s query vector. I can’t find a good example of how to do this. Anyone have ideas?
An example of what I’m talking about:
(require '[re-frame.core :as rf])
(def default-db
{:user {:favorite-book-id :foo}
:books {:foo {:title "The elements of Foo"}
:bar {:title "Thinking Bar"}
:baz {:title "What about Baz?"}}})
(rf/reg-sub
::all-books
(fn [db _]
(:books db)))
(rf/reg-sub
::book-title
:<- [::all-books]
(fn [[all-books] [_ book-id]]
(get-in all-books [book-id :title])))
(rf/reg-sub
::favorite-book-id
(fn [db _]
(get-in db [:user :favorite-book-id])))
;; I want to write a sub that gets the title of the user's favorite book.
(rf/reg-sub
::favorite-book-title
:<- [::all-books]
:<- [::favorite-book-id]
(fn [[all-books favorite-book-id] _]
;; this is all well and good, but it repeats the logic in ::book-title
(get-in all-books [favorite-book-id :title])))
I know how to do this in a view:
(defn favorite-book-view []
(let [book-id (rf/subscribe [::favorite-book-id])
;; book-id is input to book-title
book-title (rf/subscribe [::book-title @book-id])]
[:div "My favorite book is: " @book-title]))
But it looks wrong to do in a sub:
(rf/reg-sub
::favorite-book-title
(fn [_]
(let [book-id (rf/subscribe [::favorite-book-id])]
;; I assume this violates assumptions about where you can deref a sub?
[(rf/subscribe [::book-title @book-id])]))
(fn [[book-title] _]
book-title))
I think reg-sub-raw
is your best option here.
oh, perfect! so in this case, sounds like basically the same code?
(rf/reg-sub-raw
::favorite-book-title
(fn [_ _]
(reaction
(let [book-id (rf/subscribe [::favorite-book-id])]
@(rf/subscribe [::book-title @book-id])))))
Yep, LGTM.