Fork me on GitHub
#re-frame
<
2015-12-13
>
jaredly02:12:50

What’s the best way to handle a subscription that depends on props? For example

(defn my-component [a-prop]
  (let [sub (subscribe [:an-event a-prop])]
    (fn []
      [:div nil @sub] ; for example
      )))
The subscription won’t change when props change, because it’s only created on initial creation of the component. Does it make sense to do
(defn my-component [a-prop]
    [:div nil @(subscribe [:an-event a-prop])])
But that would re-subscribe on every render, not sure that would do good things

roberto03:12:32

how does your subscribe fn look like?

jaredly04:12:26

@roberto: something like (register-sub :an-event (fn [db [_ prop]] (reaction (get-in @db [:some :thing prop]))))

mikethompson05:12:34

Your first code fragment is the right one.

mikethompson05:12:46

If you are paranoid, you might write it like this:

(defn my-component [a-prop-orig]
  (let [sub (subscribe [:an-event a-prop-orig])]
    (fn [a-prop-render]
      (assert (= a-prop-orig a-prop-render))   ;; <--- paranoid
      [:div nil @sub] ; for example
      )))

jaredly05:12:32

what I want is for the subscription to change when the prop changes. and that’s not what I experienced @mikethompson

mikethompson05:12:02

Two ways of achieving that ...

mikethompson05:12:54

1. You trash the component and recreate it. It will subscribe based on the new prop. And you are all good. 2. You can use dynamic subscriptions

mikethompson05:12:36

Option 1 is achieved by putting a key on the component (which is the a-prop value)

mikethompson05:12:17

When that value changes, the key will be different, leading to the old component being trashed and a new one being put in place

mikethompson05:12:26

This is a fairly big hammer

mikethompson05:12:32

Dynamic subscriptions are the second option which is designed for exactly this situation too ....

mikethompson05:12:51

IF the parameter coming in .. a-prop in you case, is a ratom ...

mikethompson05:12:23

... ie a value which can change over time .... then .... you can pass it in the subscribe ...

mikethompson05:12:31

... as the 3rd parameter

jaredly05:12:31

feels a little weird to have a prop that’s a ratom though… but I guess in re-frame/reagent, the only way to have values changing over time is w/ ratoms

mikethompson05:12:49

So

(defn my-component [a-prop-ratom]
  (let [sub (subscribe [:an-event] [a-prop-ratom])]
    (fn []
      [:div nil @sub] ; for example
      )))

mikethompson05:12:14

Very normal and useful to have props which are ratoms

mikethompson05:12:29

Remember with ratoms you are effectively building a signal graph

mikethompson05:12:01

and the results of subscriptions are effectively ratoms (they behave as if they are ratoms)

jaredly05:12:22

well yes, but it seems like it could get confusing to have the signal graph entwined in the render tree. but I’ll get used to it simple_smile

mikethompson05:12:58

If you want to see it (passing in ratoms) in action, look at re-com

mikethompson05:12:14

(Depending on your browser targets, you may not be able to use it, but it is likely to supply some inspiration)

jaredly05:12:32

yeah, looks cool

mikethompson05:12:19

(but you'll probably have to be comfortable with CSS flexbox to understand what's going on)

jaredly06:12:18

wow that is super slick!

nickastete17:12:45

is anyone aware of an example that uses rethinkdb as a backend to a re-frame app? i've read earlier on this channel that people have done it, but i can't find any code examples

danielcompton20:12:46

@nickastete: we don’t really have any code to share at the moment

danielcompton20:12:23

although RethinkDB is writing Fusion which is a way to connect directly from a browser to a RethinkDB server ala Firebase

danielcompton20:12:30

So that will probably be where we end up

nickastete20:12:14

that's exciting

nickastete20:12:18

thanks for the update