This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-08-09
Channels
- # aleph (21)
- # architecture (5)
- # boot (25)
- # cider (1)
- # cljs-dev (115)
- # clojure (59)
- # clojure-brasil (3)
- # clojure-dev (4)
- # clojure-italy (20)
- # clojure-nl (2)
- # clojure-portugal (6)
- # clojure-russia (12)
- # clojure-spec (43)
- # clojure-uk (37)
- # clojurescript (76)
- # datomic (123)
- # emacs (3)
- # graphql (2)
- # hoplon (5)
- # jobs-discuss (1)
- # jobs-rus (4)
- # keechma (7)
- # lein-figwheel (13)
- # leiningen (7)
- # lumo (2)
- # off-topic (17)
- # om (6)
- # onyx (26)
- # parinfer (19)
- # planck (2)
- # re-frame (80)
- # reagent (9)
- # ring (1)
- # spacemacs (45)
- # testing (1)
- # vim (28)
@yedi Seems like that functionality is unreleased: https://github.com/Day8/re-frame/blob/master/CHANGES.md#minor-fixes-and-improvements
Looking forward to that addition, it makes conditional dispatches in dispatch-n a lot cleaner (as is evident in your examples)
@yedi and @curlyfry Yes, ineed, sorry about that ... the docs are ahead of the release schedule there.
You can get that functionality now if you monkey patch the dispatch-n
effect handler in your own code
(re-frame.core/reg-fx
:dispatch-n
(fn [value]
(if-not (sequential? value)
(re-frame.core/console :error "re-frame: ignoring bad :dispatch-n value. Expected a collection, got got:" value)
(doseq [event (remove nil? value)] (router/dispatch event)))))
And then remember to remove your money patch after the next release
Hi, all. I had a strange experience with re-frame subscriptions a few days ago, and wonder if there is something I’ve missed. In general terms: In ns “foo.subs” I used reg-sub to register subscription :subA. Than ns was required in “foo.core” that also utilized this subscription in a component. The problem was that I got an error telling me that there was no registered subscription for :subA. My workaround was to move this reg-sub to the top of ns foo.core, but I find it strange that I had to do this as. Any thoughts?
@curlyfry Cool! Was just worried cuz the 0.6 update mentioned "By the way, we changed a BUNCH of stuff to reflect the new JS library interop. There's probably bugs!".
Are there any publicly available examples of larger re-frame applications? I'm looking for a bit more insight in how folks structure things than the Basic App Structure (https://github.com/Day8/re-frame/blob/master/docs/Basic-App-Structure.md) page offers.
I've ended up doing kind of the opposite (e.g. I have handlers/panel.cljs + views/panel.cljs for my different areas) and I was curious to see what others have done.
@mokr It’s strange indeed. How do you use the subscription ?
(subscribe [:subA])
?
@jvuillermet Thanks for confirming. Yes, in essence that’s the code I use, but via a “listen” helper that does the deref. I believe the docs/examples also calls that kind of helper “<sub”
hi! I’m starting out with re-frame, and I’ve used a pattern like this to handle navigation between different views: https://github.com/Day8/re-frame/blob/master/docs/Navigation.md
I’m having doubts on how to add some initialization step required when a view gets activated
for example if a view displays a list of elements that comes from the backend, I want that list to be fetched and saved in the app db every time that view becomes active
would it be ok to just dispatch an initialization event inside the view? e.g.:
(defn channel-list-view
[]
(re-frame/dispatch [:channels-load])
(let [channels @(re-frame/subscribe [:channels])]
[:div
[:h2 "Channels"]
(if (empty? channels)
[:p "There are no channels yet."]
[:ul
(map channel-item-view channels)])]))
which are basically functions that return the render functions (which in turn return the hiccup for you component)
if you use a form-2
component, in the outer function you can dispatch events that run only once when you component gets mounted
so dispatch events fo rfetching the data in the outer fn and then subscribe to that date in the inner/render fn
mmm I’ve used those but I’m not sure those would match my need if I understood right how mounting works
let’s say I do it like that, if a new element gets added to the backend after I’ve loaded my app, my list won’t be refreshed until I do a full page refresh
for example, if I’m standing in the list, change the view to edit one of the elements and come back to the list
well the list will be populated from the data in the global app-state, so if that changes then your component would update correctly
so as long as you have the correct logic for updating the global app-db
then you should be fine
does it make sense to want the data to be refreshed without having to reload the app?
right then seems like you'd have to implement some sort of polling / websockets thing that watches for changes from the backend and updates your app-db
accordingly
the great thing about reframe and react is that the view should always display what the current state is, so as long as you're managing your app-db
correctly you don't have to worry about explicitly updating your view
mmm so if you were to edit an element of the list, you’d both send the corresponding request to the server and manually update it in the app-db?
(my intuition is to just send the PUT request and emit an event that causes the data to be fetched again from the server)
the way i'd do it is send a request to the backend and then flip some loading/pending state to show the user that something is happening
when the request returns from the backend, usually it would have the updated list of items. so you'd then update the app-db with the new list. (as well as remove the loading state)
so when the requests returns the app-db gets updated which automatically rerenders your view with the correct state
(i wouldn't modify the data in the app-db prematurely just in case the request errors in the backend. you don't really want your local app-db
to have changes that aren't reflected in the server... but that can be figured out on a case by case basis. sometimes its merited)
yea you'll have to implement some kind of polling thing that listens for changes from your server
i don't have too much experience implementing polling but there are tons of examples / libraries online for doing it
I think it’s overkill for my case (it’s a simple crud and no special reason to think there will be more than one user touching the same data)
just to understand a bit more, would you say that doing it like in the snippet I’ve posted below is not a good idea?
as in it doesn’t make sense to be dispatching everytime a view function is called or something like that
i would do something like this instead
(defn channel-list-view
[]
(re-frame/dispatch [:channels-load])
(fn []
(let [channels @(re-frame/subscribe [:channels])]
[:div
[:h2 "Channels"]
(if (empty? channels)
[:p "There are no channels yet."]
[:ul
(map channel-item-view channels)])])))
yeah, I know about those, just that my version does achieve that thing of always keep in sync with the backend. I wonder if it’s conceptually wrong to do it like that
also depending on how often the view is being rerendered, you'll probably not want to send a request to the backend everytime
2. rerender the view with the new channels (which would cause another request to the backend)
4. waits until your user does something to change the view or cause it to rerender, once that happens return back to 1.
yeah it’s kind of weird that when it does change you both render the view and trigger the channel fetching again
so while the app is in state 3, it won't automatically know about new changes to your backend db. you'd have to wait for the user to make the view rerender somehow
yea i think you would just want form-2 components for that. and only dispatch channel load when the list view mounts
@facundo: I'd try and start the data fetch from some event handler, I mean not necessarily right there but probably dispatching an event to do so. It could be a route change handler (if going to this list, and/or updating and going back to it involves a change in route) or an :update-item
event. Did you see the recent post from Eric Normand https://purelyfunctional.tv/article/react-vs-re-frame/? the first "thing reacters do that re-framers avoid" is basically about this 🙂
so what I did based on the article’s advice is to create an event like this
(re-frame/reg-event-fx
:switch-to-channel-list
(fn [_ _]
{:dispatch-n [[:channels-load]
[:switch-view :channel-list]]}))