Fork me on GitHub
#re-frame
<
2017-05-03
>
mikethompson00:05:39

@polymeris thanks! That would be very useful

jfntn03:05:01

Are there any issues with dereferencing a sub inside an event handler?

akiroz03:05:53

@jfntn depends if your sub parameters are constant, if they are dynamic then you are creating a new sub each time the event happens which causes a memory leak since subs are cached

akiroz03:05:14

otherwise there aren't any technical issues AFAIK, It's not idiomatic but I haven't found a good way to access some derrived state in an event handler besides using interceptors to sync the derrived state into the db.....

jfntn03:05:28

@akiroz @mikethompson thanks! I think in our case it might be okay. The sub in question is already used a lot and does some heavy lifting to retrieve a value that is the intersections of multiple selections (subs too). We already use it both in views and as a base sub for subselects etc. It seems in this case we’d want to leverage the cache to avoid recomputing from the raw db

akiroz03:05:50

@mikethompson awesome, I could definitly use an inject-sub interceptor 🙂

jfntn04:05:40

Could inject-sub be as simple as this:

(re-frame/reg-cofx
 :sub
 (fn [cofx [id :as query-vector]]
   (assoc cofx id (deref (re-frame/subscribe query-vector)))))

(defn inject-sub [query-vector]
  (re-frame/inject-cofx :sub query-vector))

;; Usage:

(re-frame/reg-event-fx
 ::my-event
 [(inject-sub [::foo/bar])]
 (fn [{:keys [db] ::foo/keys [bar] :as cofx} _]
   ;; derefed ::foo/bar is accessible here...
   ))

jfntn04:05:03

I don’t understand what you mean by disposing of the subscription in the posted you linked to mike?

mikethompson04:05:25

When you do (re-frame/subscribe query-vector) a subscription is created which will deliver a stream of values over time. Normally such a subscription is "destroyed" when the Reagent component which is using it is destroyed (assuming no other reagent component is also using it).

mikethompson04:05:00

So the problem with doing a one off (re-frame/subscribe query-vector) is that the subscription is left sitting there and is never destroyed.

jfntn04:05:00

Ah got it, but in our case we’d want to hit the cache

mikethompson04:05:20

If a subscription is cached then that value would be used

mikethompson04:05:49

So you can "get away with it" in particular circumstances

mikethompson04:05:58

But what you've done is not general

mikethompson04:05:03

To get a general solution, we'd need to get the value out of the subscription, then despose of it. But only when it is not otherwise being used

mikethompson04:05:37

Remember that one subscription can trigger the existance of another. Multiple levels potentially

jfntn04:05:23

Ok I see, thanks for the explanation. I’m not very familiar with reagent’s or re-frame’s internals, but at first glance, and assuming subscribe always returns a reaction, you would start by checking the reaction’s watching and walk the graph from there, checking for every parent reaction if there is only one watches you can get rid of that too.

mikethompson05:05:43

Sure, its certainly possible. It is just that noone has done it yet :-)

eveko07:05:21

is it possible to dispatch an event based on an timer? Say expiring a token after x amount of time?

eveko07:05:06

awesome hiding in plain sight ( or not being that good with looking up the things i need )

tomaas10:05:21

Hi, I'm using the latest re-com version and using :status :succes on input-text component I get an error

tomaas10:05:35

Invalid return from validate-fn: Invalid :status. Expected one of [:warning :error]

jfntn14:05:32

@mikethompson I was playing around with the disposal logic for inject-sub and I saw a behavior that didn’t match my expectations: if I reg and inject a sub :c that composes subs :a and :b (say with the :<- syntax) if no components uses :c when the sub injector invokes (subscribe [:c]) it gets a reaction that has no watches or watching which I found surprising since I expected it to watch :a and :b. Would you mind explaining why that is?

jfntn16:05:27

hmm I think I realize what the issue is with the example I described above: if a sub is not derefed inside a view it won’t get recomputed as expected, correct? If so inject-sub could cause some unexpected behaviors if you happen to inject a sub that’s not used anywhere in you views, wouldn’t it?

sashton18:05:22

given the following db:

{:displayed-value-ids [1 3 5]
 :values {1 "one"
          2 "two"
          3 "three"
          4 "four"
          5 "five"}}
what would be the “best” way to register a subscription handler which will return the values of the :displayed-value-ids. So for example:
@(rf/subscribe [:displayed-values])
=> ["one" "three" "five"]

sashton18:05:15

this is what i’ve come up with but i’m not sure if deref-ing in the handler function is a good idea:

(rf/reg-sub
 :displayed-values
 (fn [_]
   (rf/subscribe [:value-ids]))
 (fn [ids]
   (->> (map #(rf/subscribe [:value %]) ids)
        (map deref)
        (doall))))

souenzzo18:05:01

you cant(?) subscribe from events/subs. For subs, there is the :< sugar

qqq19:05:05

without using re-com, when using [:input {:onkeypress .... }] how do I update the model with the correct value after a keypress ?

sashton19:05:16

@musheddev seeing that made me realized that i simplified my example too much. 😄 the “values” in my app aren’t static values from the db, but are derived values themselves (via subscribe). i’m trying to think of a good example to demonstrate

sashton19:05:37

@qqq does this work for you:

[:input {:on-key-press #(rf/dispatch [:update-my-field (.-key %)])}]

qqq19:05:50

no, having weird problems with :on-key-press

qqq19:05:54

but :on-change worked fine

qqq19:05:15

oh, my question was poorly phrased; I didn't realize ZI anted (.-value (.-target e))

sashton19:05:59

yeah, key-press will give you the value of the input before the new character is added. :on-key-up will fire after the value has been added to the input. :on-change as well

qqq19:05:20

I read somewhere that on-change only works "on blur"

qqq19:05:28

i.e. you have to click outside (which is not what I want)

qqq19:05:38

but somehow, in my app, it works normally when I press buttons

sashton19:05:40

does on-key-up work?

qqq19:05:52

:on-change 'works', but is not supposed to according to docs I have read

musheddev19:05:35

@sashton In that case, I wouldn't have a subscription for each value but one for the whole set, and subscribe to both that and the id list in the first subscription function, and then do something similar to what I suggested.

naomarik22:05:28

anyone using graphql with their components?

naomarik22:05:35

wondering how that would fit into re-frame

kishanov23:05:06

we do but in very naive way: our re-frame-http-fx sends POST requests with GraphQL payload and saves the data to the database. after that components just subscribe to the different parts of response/different responses

naomarik23:05:16

are you using lacinia as GraphQL backend? also what’s the experience like working with GraphQL? positive?

kishanov23:05:16

our back-end is in Python, on a front-end we made a simple helper to build graphql queries. Overall experience is positive, however, things like powerful search on graphql queries is not there yet

kishanov23:05:34

That’s pretty much how we live with GraphQL to build queries. Subscribing to response from GraphQL query is no different from subscribing to response from simple GET to REST-like API