This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-05-05
Channels
- # beginners (12)
- # calva (18)
- # cider (1)
- # cljs-dev (29)
- # clojure (97)
- # clojure-uk (18)
- # clojurescript (10)
- # clojureverse-ops (2)
- # cursive (7)
- # emacs (10)
- # fulcro (42)
- # graphql (36)
- # joker (1)
- # juxt (28)
- # mount (2)
- # other-languages (2)
- # pathom (1)
- # portkey (3)
- # re-frame (50)
- # shadow-cljs (42)
- # spacemacs (4)
- # sql (6)
- # yada (6)
is there a better pattern for it? just looking for the best/most obvious way to react after 2 or more async things happen. like, i dispatch-n
a couple ajax calls, and want to do something when they’re done.
it sounds like the issue is that (assuming your using the relatively standard one) the ajax effect handler has a 1:1 to event and ajax effect
Managing two async events (either of which might fail or timeout) makes the state machine more complicated.
I would consider writing an effect handler that would fire the 2 ajax as one effect
defining the state transitions locally in the event/effect makes more sense to me than spreading it over multiple events/effects
The firing of the events is the easy bit :-)
dispatch-n
easily fires two events
The challenge is in subsequently managing the consequential state machine
That's kinda why we wrote async flow
But it feels like overkill for such a simple case
probably the 80% case could be solved by an effect like:
{:http-n {:requests [{...}] :on-all-success [::success-result] :on-failure [::failure-result]}
today, i hold some sort of "in flight" id in the app db, and set that as an arg in my on-success
handlers, so they know what "group" of events they belong to. it's a decent amount of bookkeeping. the chaining of promises, while not really simpatico with the "dispatched events" style, has some advantages. in any case, i'll try to think harder about it, and see if anything shakes out. thanks for responding!
Beginner question on the 'right' way to do something. I am making a loan calculator, so it has values like interest
, term
, price
, down-payment
, principal
, monthly-payment
. Changing some of these values changes more than one of the others, for example changing price
should change principal
and monthly-payment
, same for changing down-payment
. How do people manage events that cause other data to change also? I can do it in a verbose way just by recomputing all the other values that need to change in each particular event handler. Is there a more concise and idiomatic way to mange it? Fire other event(s) from an event handler? I'm thinking of Excel-style flow where I define the 'formula' for the data in terms of each other, not sure if that's reasonable here.
I would try and separate your values into ones that are independent and ones that are dependent
the independent ones can live in your state, and the dependent ones can be computed based on the state
I think some of the dependent ones such as monthly-payment
will be used downstream to e.g. plot a graph of the balance over time
I was thinking of writing some helper function that computes the ~5 values together as a map when any of them change, and calling that from each of the event handlers for the 'independent' values. Just didn't know if there was some idiomatic way of handling that with more events or something
values that depend on state shouldn’t be computed in event handlers. instead, they should be computed in subscriptions
so you might a subscription called :loan/monthly-payment
that is computed via values from the app-db, and then your calculator and graph views can both subscribe to it via (rf/subscribe [:loan/monthly-payment])
I think that would work well for that one, thanks!
Not sure how to handle values that can either change from user input for because another upstream value changed. An example is amount-down
(the down payment in dollars), which can change either from user input or because percent-down
(the % down payment) changes.
in your handler for the user changing their percent down, you can calculate the amount-down
based on the price and commit that to the app-db
basically, you want to try and maintain one source of truth for each “fact”. if you have multiple entries in the app-db tracking the same things, you end up having complicated coordination where multiple values need to be changed simultaneously, always
Ok this is making more sense :thumbsup: so the values at the bottom of the event graph basically that don't change other values, make subs for those
I guess one that might still be verbose is changing price
? That event handler would have to change price
, percent-down
. That's not too bad though.
you could have an :loan/update-percent-down
event which computes the amount-down
and commits that to the app-db. and then a :loan/percent-down
subscription which computes the percentage down based on price
and amount-down
this way you only keep track of the “Amount a person must pay down” in one place in the DB.
you could obviously flip this the other way and track percent-down
in the app-db and have amount-down
be calculated
Don't I need to track both of them in the db since both can be changed by the user?
Or are you saying like don't track one of them to simplify
if two keys are always changed in sync, you are probably tracking it multiple times
Make sense, percent-down
is basically a 'view'
amount-down
is the main piece of data
yep. E.g. when someone updates the percent down:
(reg-event :loan/update-percent-down
(fn [cofx [_ new-percent]]
(let [price (get-in cofx [:db :loan :price]
new-amount (* price new-percent)]
{:db (assoc-in (:db cofx) [:loan :amount-down] new-amount)})))
(reg-sub :loan/percent-down
(fn [db _]
(/ (get-in db [:loan :amount-down]) (get-in db [:loan :price]))))
Thanks, this is very helpful!
Is there a reason for using reg-event :loan/update-percent-down
(I think it's actually reg-event-fx
right) instead of reg-event-db
?
Cool I think that's all that would be doing right?