re-frame

https://github.com/Day8/re-frame/blob/master/docs/README.md https://github.com/Day8/re-frame/blob/master/docs/External-Resources.md
paulbutcher 2020-11-11T12:15:54.303500Z

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-himik 2020-11-11T12:22:14.303600Z

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.

paulbutcher 2020-11-11T12:23:30.303800Z

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

tugh 2020-11-11T13:44:22.304500Z

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

tugh 2020-11-11T13:45:46.305100Z

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-himik 2020-11-11T14:00:52.305200Z

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

👍 1
p-himik 2020-11-11T14:02:02.305400Z

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.

paulbutcher 2020-11-11T16:39:58.305600Z

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.

Mike Richards 2020-11-11T17:09:09.306700Z

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 Richards 2020-11-11T17:09:20.306900Z

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 Richards 2020-11-11T17:10:30.307100Z

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 Richards 2020-11-11T17:11:36.307300Z

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-himik 2020-11-11T17:14:12.307400Z

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

Mike Richards 2020-11-11T17:23:35.307800Z

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-himik 2020-11-11T18:43:38.308Z

Yep, LGTM.

👍 1