This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-11-02
Channels
- # announcements (2)
- # babashka (10)
- # beginners (61)
- # calva (17)
- # cider (27)
- # clj-kondo (14)
- # clojure (230)
- # clojure-austin (4)
- # clojure-europe (17)
- # clojure-france (6)
- # clojure-hungary (3)
- # clojure-norway (30)
- # clojure-sweden (9)
- # clojure-uk (2)
- # clojurescript (58)
- # conjure (11)
- # core-async (7)
- # cursive (74)
- # datalog (2)
- # datomic (15)
- # events (8)
- # figwheel-main (5)
- # fulcro (2)
- # graalvm (23)
- # graphql (2)
- # helix (17)
- # humbleui (2)
- # jobs (2)
- # kaocha (6)
- # lsp (19)
- # malli (7)
- # nbb (51)
- # off-topic (33)
- # pathom (26)
- # pedestal (2)
- # polylith (1)
- # portal (4)
- # re-frame (17)
- # react (3)
- # reitit (5)
- # releases (2)
- # remote-jobs (2)
- # shadow-cljs (18)
- # sql (65)
- # tools-deps (8)
- # xtdb (28)
Is it possible to use the output of one signal function as the input of another? Is something like the below possible with just reg-sub?
(rf/reg-sub
::item
(fn [db [_ id]]
(get-in db [:items id])))
(rf/reg-sub
::highlight
:-> :highlight)
(let [hl-id @(subscribe [::subs/highlight])
hl-item @(subscribe [::subs/item highlight-id])]
,,,)
Apart from the hl-id
/`highlight-id` typo, your code should work just fine. That's a pattern that re-frame documentation itself often uses.
Doesn't this make the component it's used in re-render at every db change? I'd hoped to make a subscription that somehow combines ::highlight and ::item (pipe the result of highlight into ::item)
No, i twill be re-rendered only when either of those subs changes its value. Unrelated app-db changes won't result in re-rendering.
But you can still make a sub that combines those two. The simplest in this case would be to use reg-sub-raw
.
> re-rendered only when either of those subs changes In that case it's moot. Gonna just combine them in the view. I checked reg-sub-raw, but as the name suggests it's pretty raw.
It's not a downside though.
(rf/reg-sub-raw ::highlighted-item
(fn [db _]
(r/reaction (get-in @db [:items @(rf/subscribe [::highlight])]))))
Or:
(rf/reg-sub-raw ::highlighted-item
(fn [_ _]
(rf/subscribe [::item @(rf/subscribe [::highlight])])))
Looks like I have shot myself in the foot by having a lot of "view", domain-logic functions taking db
liberally. The pieces are very flexible. But now any subscription I made of them will invoke them every time db changes. Do you guys clearly separate simple getter functions (db -> not-db) from computation functions (not-db -> not-db)? It will be a major re-factoring for me. Is there any clever solution here?
Views shouldn't care about the internal app-db structure.
I like the approach where you have two kinds of data - one is the domain data (things you'd put in a relational DB) and the other is the app data (current user, current panel, active dialogs, etc.)
For the first, I store the data in a specific normalized way and query it using some specific subs that are common for all views and data entities. The sub is called just :q
.
For the second, I create ad-hoc subs for every necessary value with a reasonable level of granularity.
Thanks. Actually, the shape of my problem looks very much as follow:
(defn foo-a [db a]
(let [b (some-computation-a db a)]
(foo-b db b)))
(defn foo-b [db b]
(some-computation-b db b))
(f/reg-sub ::foo-a
(fn [db [_ a]]
(foo-a a)))
I guess I'm looking for ways to run less computations without having to refactor too much. What do you think?It's a reasonable approach to refactor all your subs and events into functions with similar input/output shapes with actual handlers just combining those functions. And it can be a gradual process, which is nice.
I've solved my problem! I think my question wasn't clear. My namespaces are actually already separated into clear domains. And so, I can use information about each domain to limit the scope without changing any structure!
(f/reg-sub :select-keys
(fn [db [_ keys]]
(select-keys db keys)))
(f/reg-sub ::get-value
:<- [:select-keys #{:data :updated-data}))]
(fn [db [_ data-path opt]]
(utils/get-merged-value db data-path opt)))
Thank you.yep https://github.com/day8/re-frame/blob/5cfc9b8ec00aa4275b1716b9d453e41cf04495a6/src/re_frame/subs.cljc#L173 simply removes the args so you don't get edge cases where a keyword doesn't exist in add-db returning the arguments to the subscription