Fork me on GitHub
#re-frame
<
2017-07-26
>
danielcompton03:07:16

@jfntn subgraph looks very cool. I especially like how easy it is to get data into it. Mike and I took a look at it and had a few questions: * How do you do a pull-many? Just map over the entities with a pull? * Would you ever remove stuff from the subgraph, or does it mostly accrete over time? * Why did you build this instead of using Datascript? (not saying you should have, just trying to understand the design decisions) Probably the biggest question we have is how do you query the subgraph? How do you know which entities to query for?

danielcompton05:07:39

@jfntn thanks, that's really detailed!

danielcompton06:07:12

On performance, are all subscriptions recalculated every time the subgraph db changes? It seemed like that would probably be what would happen

jfntn06:07:57

Yes indeed, if you’ve any ideas re. optimization I’d love to hear them

jfntn06:07:15

What happens in practice is a bit subtle because when we pull A that joins B we’ll create 2 reactions. I opened an issue to consider using the re-frame sub cache instead which might help?

danielcompton08:07:23

Yeah, the idea would be to chain the reactions so that they can short circuit as soon as possible. Anytime app-db changes, it will cause a recalculation of every subscription that depends on app-db

danielcompton08:07:17

But if you first take a subscription just for the path to the subgraph, and then make a subscription off that path for the sources for the final subscription then that would cut down on unnecessary expensive recalculations

danielcompton08:07:36

And because they are deduped, you would only pay most of the costs once no matter how many subs you have

pesterhazy09:07:11

Question for the re-frame pros: Should all re-frame events or effects be data? In particular, do you pass objects or callbacks as parameters to re-frame events or effects? [:launch-missle (fn [] (js/alert "foo"))]

danielcompton09:07:36

This is a little bit of a tricky one

danielcompton09:07:05

as you've probably noticed, if all 'callbacks' have to be reframe events, then you end up with a lot of boilerplaty code

danielcompton09:07:54

OTOH, if you pass non-data to events then you lose replayability afterwards, e.g. replaying a failed user session to debug where it failed

pesterhazy09:07:26

yeah that seems giving up on a big advantage of re-frame

pesterhazy09:07:31

with your first point, did you suggest specifying callbacks as reframe events?

pesterhazy09:07:13

E.g.: [:launch-missile [:notify-user "Job completed"]]

danielcompton09:07:20

we do that a bit

pesterhazy09:07:44

yeah that might work

pesterhazy09:07:14

frankly passing functions just feels wrong - they can't be pretty printed, they're opaque, can't be serialized

pesterhazy09:07:40

ah that's really helpful

pesterhazy09:07:03

is the result injected into [:good-http-result]?

pesterhazy09:07:13

this is a nice pattern, will try that

mccraigmccraig09:07:40

we often pass "partial" re-frame events like that - data gets appended to the end of the vector before dispatch

mikethompson09:07:19

We have used the term "dispatch-backs" rather than "call-backs"

mikethompson09:07:00

Ie. don't pass in a callback function. Pass in the event to dispatch (which can get conjed with more data)

pesterhazy09:07:17

dispatch-back, love it

mikethompson09:07:57

A bit abstract, I know :-)

danielneal11:07:18

ah awesome 🙂

lumpy11:07:09

Do people use similar helper functions like this? Is there a reason not to do this?

(defn reg-subs [ns subs]

  (doseq [type subs]
    (let [[sub default] type]
      (rf/reg-sub
        (keyword (str ns) (str sub))
        (fn [db _]
          (get-in db [(keyword ns) (keyword (str sub))] default))))))

mbertheau12:07:48

@mikethompson argues against this approach in https://github.com/Day8/re-frame/blob/master/docs/SubscriptionsCleanup.md#a-final-faq but I personally think the reasoning is BS 🙂

lumpy12:07:28

I think this is very different than what he warns against. There is still an actual sub for each subscriber, my function gets called in the subs ns not the views ns

mikethompson13:07:07

@mbertheau re-frame is a broad church which actively encourages dissenting views :-)

joshkh13:07:49

will there ever be consideration for making re-frame apps easier to embed in other re-frame apps? i work on an app that runs standalone as well as inside a larger app which means every subscription, every event, and every view needs some location vector passed to it. it also needs to appear in every single subscribe and dispatch. it gets tedious as a project grows... for example: https://github.com/intermine/im-tables-3/blob/outerjoins/src/im_tables/subs.cljs

joshkh13:07:12

not a big deal, but passing around a location vector also means we can't use dynamic subscription sugar

joshkh13:07:43

i've resorted to attaching an interceptor to every event which temporarily sandboxes app-db so that my event functions look normal, but it expects that a location vector is the first value in the event vector https://github.com/intermine/im-tables-3/blob/outerjoins/src/im_tables/interceptors.cljs#L4

joshkh13:07:00

anyway, just wondering if that's on people's minds

mbertheau13:07:42

@mikethompson Wouldn't and couldn't be part of it otherwise! 🙂

musheddev16:07:32

@joshkh I do componentization like that, I find that it works quite well but yes passing a key/name for everything is a bit tedious. I am thinking that some abstraction could be done on an initialization function where the initial `{:name component-stuff} is written to the db, events and subscriptions could also be registered at that time but I haven't tried anything.

pcj17:07:36

What's a good way to acclimate someone to re-frame? I had him read an introduction to clojure and had him read the documentation to reagent and re-frame. I also worked through a few examples.

pcj17:07:13

Is there not much more I can do other than just wait?

jakemcc17:07:58

@pcj Pair with them while working on projects that use it. I think that greatly accelerates learning

jebberjeb17:07:02

@pcj do they already know React?

kenny18:07:13

Has anyone use re-frame with the latest Reagent 0.7.0? Any issues?

pcj18:07:52

@jakemcc I will be doing exactly this. @jebberjeb They understand React as a concept. Should I add some react literature as well?

jebberjeb18:07:34

@pcj from my own experience, I'd just taken the day or so to read over the React basics, go through a tutorial where I actually wrote some Javascript & created React classes, before diving into Reagent. My first Reagent project was non-trivial and I ended up needing to understand the React lifecycle pretty thoroughly. I wish I'd had more of a comfort level with that first.

jebberjeb18:07:21

Then again, maybe that's a hindsight bias. But it makes sense to me to learn one thing, then the next thing, sequentially, rather than tackling them both together.

jebberjeb18:07:33

Maybe it depends on what you're making.

yedi18:07:56

hey all, i'm thinking of passing a callback as an argument for an event. it gets called after some async effect handler completes

yedi18:07:15

is there anything wrong with the idea of passing callbacks to events

mccraigmccraig18:07:41

@yedi search this channel for "dispatch-back" earlier today for a better solution - callbacks are opaque

yedi18:07:31

oh cool, will do

pcj18:07:59

@jebberjeb Thanks for the advice! I actually learned reagent before even looking at React. It's doable but I did have some trouble at first with the lifecycle methods. Our project does involve a lot of c3 charts so teaching React first would actually be pretty helpful.

joshkh20:07:31

@musheddev that's a really interesting approach

joshkh20:07:53

my initial gripe came from when i wrote the data table app as a standalone application, and then someone else came along and asked how to integrate into their larger app. it meant rewriting the logic for every single aspect of the application because i didn't take a relative app-db location into account. having some sort of initialisation of nested components / subs / events would have made it much more friendly. now, when i write an application, i feel compelled to pass around location just in case.