This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-10
Channels
- # beginners (151)
- # cider (41)
- # cljdoc (7)
- # cljs-dev (6)
- # clojure (92)
- # clojure-dev (5)
- # clojure-italy (26)
- # clojure-losangeles (1)
- # clojure-nl (10)
- # clojure-russia (3)
- # clojure-spec (23)
- # clojure-uk (82)
- # clojurescript (56)
- # clojutre (1)
- # core-async (3)
- # cursive (15)
- # datomic (26)
- # editors (3)
- # emacs (3)
- # events (2)
- # figwheel-main (192)
- # fulcro (66)
- # leiningen (12)
- # mount (1)
- # off-topic (131)
- # portkey (6)
- # re-frame (38)
- # reagent (10)
- # reitit (7)
- # ring-swagger (55)
- # shadow-cljs (21)
- # spacemacs (11)
- # tools-deps (48)
Hello, is there an efficient way or recommend way to convert a jQuery based project into re-frame? Or any advice, best practice? I got the frontend code from a designer. He bought the code from http://themeforest.net, it used a bunch of jQuery libs and Bootstrap.js. Thanks.
This may help: https://github.com/Day8/re-frame/blob/master/docs/Using-Stateful-JS-Components.md
kinda
Thanks! Mike. Checking now.
@mikethompson Yeah, event handlers, not effect. I'm thinking if it makes sense to inject subs in the event handlers. I wouldn't need the reactivity, but now I'm often duplicating the db structure logic in two places. Or rather three, since there are also the events that write to the db. Not sure if the db is a mess, might be! Actually originally all of these params were inside one root key in db, but I found it quite opaque when the event handler was extremely generic – pretty much just "write this parameter value into parameter key, whatever those params are", so I started to flatten it and make separate event handlers for all form elements. I have a bunch of toggles, autocompletes/text fields etc. that pretty much set REST query params like "destination", "product", "date", "time" and so on
Hm, maybe it would be clearer if I had division based on e2e functionality, and not type. That is, instead of having subs.cljs, events.cljs and so on, I would have the subscriptions, events and components related to same functionality in the same file
Database structure: keys with prefixes/"namespaces" or nesting? I.e. {:panel1-destination "London"}
or {:panel1 {:destination "London"}}
?
hi, I have a 'failure to update' problem that has me pulling my hair out. I have a subscription that when looking at it via 10x seems to have updated as I expect, but the correponding component isn't re-rendering. In this snippet
(let [run-id (-> args :route-params :id uuid)
run (<sub [:: [:runs/by-id run-id]])
summary (rf/subscribe [::samplesummary-by-runid run-id])]
(log/debug "id" run-id)
(log/debug "summary" @summary)
(fn []
[render-summary summary])
...
summary
is nil as expected the first time through. after that render, I'm making a server call, whose successful response is updating the value pointed to by the subscription. In the inspector, I see that the subscription value is correct per my post-load fx. I've done a lot of mucking around with this, moved the subscription out of render-summary
made the component in the above snippet a form-2, etc etc but nothing seems to be making it happyI’m guessing that’s React failing to notice the change. Try manually setting a key on the rendered element and including the updated value in the key.
(fn []
^{:key (str "summary-key-" summary)}
[render-summary summary])
will give that a shot, my use case seems pretty straightforward so really not getting why it's unhappy
@manutter51 thanks. that worked.
Hello fellow re-framers. I'm new to both Clojure(script) and re-frame! After studying the framework for a while, I have a question that I couldn't find any mention elsewhere.
As a starter project, I'm building a simple user/pass login form. The form data is hold on the DB as {:username "", :password ""}
. When the user clicks on "submit", I dispatch a form-submit
event that will be handled elsewhere. My question is, how should I pass my form data (username and password) to the event handler? The way I see, I have three options:
;; (Below is just pseudo-code, not necessarily valid)
;; First option - subscribe db on view and send data alongside the event
(defn my-view
[]
(let [username @(rf/subscribe [:username])
password @(rf/subscribe [:password])]
[:input {:on-click (rf/dispatch "form-submit" user pass})]))
;; Second option - send event without data; subscribe db on HANDLER
(reg-event-fx
:form-submit
(fn [_ _]
(let [username @(rf/subscribe [:username])
password @(rf/subscribe [:password])]
;handle)))
;; Third option - send event without data; fetch data from db directly
(reg-event-fx
:form-submit
(fn [db _]
(let [username (get-in db :username)
password (get-in db :password)]
;handle)))
Personally, I like the second approach best, because I end up with only one place to declare how the data should be fetched (the subscription) and the view is a bit clearer. But I've never seen subscription being used outside other subscription or from the view, and the handler does not need in any way to be reactive, so I don't know if this is a valid approach, overkill or an anti-pattern. Thoughts?Hi @renato, couple things. First you generally don't want subscriptions 'inside' your event handlers, as is the case in your second option. Second, for forms there's two approaches to this in general, so it's going to be a matter of personal peference on your part. You can simply use a reagent ratom to hold your 'local' form state, then dispatch the values you need in in your form-submit event. So sort of like your first option. Alternatively you can have reframe itself manage your form state, under some useful keys in your db :login-form/username ..
or :login/form {:username ...
etc etc, but even then, I'd pass the values as args to the event
Hey, thanks for the reply. Any special reason why it shouldn't be "inside" the subscription? Perhaps it would make it impure?
@renato I agree with what @eoliphant suggested. I just want to point out, there may be cases where it is convenient/useful to “inject a subscription value” into a event handler.
https://github.com/vimsical/re-frame-utils#cofx is lib that exists for this and it does it in a re-frame
-style
However, it’s probably best to only use it when there aren’t cleaner alternatives as suggested above.
There are some caveats to using subscriptions as cofx/etc within event handlers. Most prominently is the cache and clean-up of the subscriptions.
Lots of discussion on that particular topic @ https://github.com/Day8/re-frame/issues/255
Thanks a lot! Great discussion, and there's actually an entry about this in the FAQ (which I've read more than once). Feeling kinda silly now 😅
Don't feel silly. I have the same exact problem that I need to make requests to the backend, and need the request params from all over the db. Just hard coding the db paths in the "send" handler feels fragile
I hadn't considered the option of subscribing in the button and then using event params. That feels too much like coupling the button. Doesn't seem like the visual component should need to know what params are needed. Makes more sense if the whole form is a reagent component, that links to re-frame only when the button is pressed
First I thought that with over 2k commits, it's rather well established. But seems like the author likes splitting everything into ten commits... https://github.com/reframejs/reframe/commits/master?after=fd42394ac7433a0a41314c3c1042a9aa2ee20da2+34
Yeah, IMO it was a poor decision by him to continue with the name once the clash was pointed out. Shrug. Moving on.
> That feels too much like coupling the button. Doesn't seem like the visual component should need to know what params are needed
Yep, that's the reason I didn't want to do this in the view directly. The view could simply state the intent (`submit-form`) and the handler would fetch the required data. The inject-sub
on re-frame-utils
seems a nice compromise (decouples this logic from the view, keeps the handler pure, does not impact performance (apparently)).
(Just for the record, I don't think passing the params directly on the view is bad / highly coupled - in fact it's the most common approach. I just think that something like inject-sub
decouples it even further)
> does not impact performance (apparently)). This part, it can affect perf if only the event handler needs the sub
The warning will be something like “the injected subs X is only used in the event handler”
when that is the case, the sub is immediately cleared from the cache to avoid a memory leak
I don’t remember all the specifics, but that is the caveat to look out with regarding performance
Correct. It's mentioned in the code (and on issue #255) but maybe a disclaimer at the project's readme would be better. I won't submit a PR because it seems unmaintained though (or rather finished)
Can anyone recommend a largeish re-frame app that I can check out for best practices? I've looked through some smaller examples but interested to see what changes at scale
This series builds out a moderately sized full stack app that includes re-frame: https://www.stuttaford.me/2018/02/18/a-clojure-learning-journey/