This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-11-19
Channels
- # announcements (5)
- # beginners (68)
- # boot (1)
- # cider (27)
- # clara (11)
- # cljdoc (10)
- # clojure (129)
- # clojure-europe (2)
- # clojure-italy (16)
- # clojure-nl (15)
- # clojure-spec (74)
- # clojure-uk (31)
- # clojurescript (62)
- # core-async (17)
- # cursive (28)
- # datomic (22)
- # duct (29)
- # emacs (10)
- # fulcro (65)
- # hoplon (2)
- # hyperfiddle (16)
- # instaparse (3)
- # kaocha (2)
- # lein-figwheel (3)
- # leiningen (1)
- # mount (1)
- # nrepl (21)
- # off-topic (23)
- # re-frame (59)
- # reitit (18)
- # ring-swagger (2)
- # shadow-cljs (2)
- # spacemacs (16)
- # timbre (2)
- # tools-deps (22)
There are a set of links at the top of that page which explain it. In essence ... > Views are not imperative and they don't initiate database queries. Instead, views are simply a rendering of the current application state.
@achikin so please be sure to read through the material on the end of those provided links.
I have read the links. Those articles does not explain real practical downsides of fetching data inside a subscription.
Moreover is seems like fetching using an event encourages more imperative approach when you need to provide concrete steps for fetching data for each component instead of doing it in a more reactive way as when you fetch data from a re-frame database itself.
In re-frame, nothing "new" happens without an event. In turn, it is the associated event handler which knows how the event should change the world. In which case, it is event handlers which initiate (via an effect) the fetch.
it is reactive, not imperative.
Imperative stuff happens via event handlers (and the effects they nominate)
> The job of a subscription is to simply deliver data Why is there a difference between delivering from re-frame database and delivering from a server?
So in re-frame, views are not imperative. And neither are subscriptions. They are simply nodes in a reactive signal graph.
Delivering from a server is stateful and async, etc.
There are timeouts and failures, etc.
Let's imagine I have fired and event to deliver some data from a server and then I've rendered a component, which is subscribed to that data. Exactly as you suggest. It is async and prone to timeouts and failures too.
Yes, so the goal is to limit that kind of stateful logic to event handlers. Spreading that kind of logic around into views or their subscriptions is not recommended.
After all, if you want to, you can just put the GET into the view itself componentWillMount
Why bother putting it into a subscription?
But hey. If you believe you want to make subscriptions side-effect-y, the blueprint is there in that document. We certainly explored it and then backed away. But your experience may be different.
> After all, if you want to, you can just put the GET into the view itself componentWillMount
You have provided good reasons not to do that. Especially that components become less reusable when they are coupled with requests.
It doesn't sound like I've convinced you
I'll put some more thought into my explanations, but that's all I got for the moment :-)
But subscriptions are about fetching data from a model, so I'm trying to understand why can't they fetch from the server.
No, not at all.
I just explained my reasons
But they were obviously not very convincing for you
For me, the reason is simple: don't make subscriptions have side effects.
Only event handlers should have side effects.
In our experience, that rule simplified things.
> For me, the reason is simple: don't make subscriptions have side effects. I expected something like "We did this in our project and that lead to this, this and that" rather than "should not have side effects because should not have side effects"
Believe me I do understand your general line and efforts to separate and isolate side effects. I just wonder if it worth it from practical standpoint.
If we could fire fetch events from subscriptions - we could care less about repeating fetch events in every view change event. This is a huge plus. But what are the downsides?
A more complicated computational model
Because side effects can happen in more places.
Everything is a trade off. I find it useful to keep the role of each domino clearly delineated.
I hope all that was useful. Gotta go.
Useful even if I didn't provide compelling reasons in your view
Nite.
@achikin I don't have much time right now but I slept on my explanations and would put my position like this ...
We're programmers and we create abstractions for a living because it is our primary weapon for controlling complexity.
As a result, when we hear subscriptions access data from app-db
we're tempted to turn it into the more general (abstract) idea that subscriptions access data
including from the server.
I actually went down this path at one point (hence the documentation on how to do it) but realised it broke another more important abstraction in re-frame - the computational model.
It makes subscriptions side-effect-y and there's always a cost for side-effect-y-ness. re-frame goes to a fair bit of effort to corral side-effects into just one place (one domino) because the overall architecture and the apps it produces are easier to understand as a result.
State machines are simpler to understand than full Turing machines because of the constraints they impose on computation.
re-frame constrains you too and (hopefully) produces a simpler computational model as a result. One of the constraints is that side-effect-y stuff only happens in one place.
All of the above is pretty much what I originally said, but perhaps repackaged to make more sense. Maybe.
Vaguely related: https://github.com/Day8/re-frame/blob/master/docs/MentalModelOmnibus.md#on-dsls-and-machines
Also, have a look at ... https://purelyfunctional.tv/article/react-vs-re-frame/ specifically the section "Reacters load data on mount"
Is there a way to register a global interceptor that is executed for all events? I am specing my :db
and would like this check to be executed everywhere to catch trouble as quickly as possible.
@urzds It is common to define common interceptors in var and use them everywhere (or wherever you want)
https://github.com/Day8/re-frame/blob/master/docs/Debugging-Event-Handlers.md#too-much-repetition---part-1 describes the pattern
@urzds Not that I know of. My solution is usually to make my own event registration functions that call the re-frame ones with some interceptors
Is it possible to "hook into re-frame's specs"? I.e. use re-frame's specs, but add my own for :db
, which re-frame cannot spec by itself?
@urzds I did db-specing for kee-frame, check it out here: https://github.com/ingesolvoll/kee-frame/blob/master/src/kee_frame/spec.cljc
Basically you can´t really “extend” the framework like that, but you can wrap it with your own functions
@urzds @ingesol @mikerod FAQ #13 covers this issue I believe https://github.com/Day8/re-frame/tree/master/docs/FAQs
@mikethompson ah yes, that’s better than the link I mentioned
@mikerod yeah, it is an indictment on the organisation of the docs that people know they've read something sometime, but then can't find it again. But I'm not sure what to do about it.
well, FAQ was a pretty obvious place to look for this - I should have thought that. It is hard to know what to do about the general situation though. I do know I’ve knew I read something there before, but had to search a bit to find it. The organization overall is good and coherent. It’s just recalling the location of specific details I think.