Fork me on GitHub
#re-frame
<
2020-11-11
>
paulbutcher12:11:54

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!

p-himik12:11:14

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.

paulbutcher12:11:30

Good thought. I’ll do so unless anyone has any immediate thoughts about what might be going on. Thanks!

paulbutcher16:11:58

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.

tugh13:11:22

is there a way to register events locally instead of globally? like private functions

tugh13:11:46

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]}]})))

p-himik14:11:52

No. FWIW I just prepend - to such event IDs to make them different from the others, like ::-start-thinking.

👍 1
p-himik14:11:02

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.

tugh07:11:32

alternative solution feels too low level. i also wouldnt do such a thing 🙂 thanks for your answer! 🙌

Mike Richards17:11:09

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?

Mike Richards17:11:20

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])))

Mike Richards17:11:30

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]))

Mike Richards17:11:36

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))

p-himik17:11:12

I think reg-sub-raw is your best option here.

Mike Richards17:11:35

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])))))

p-himik18:11:38

Yep, LGTM.

👍 1