This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-09-05
Channels
- # announcements (7)
- # beginners (107)
- # boot (5)
- # calva (2)
- # cider (18)
- # clj-kondo (48)
- # cljs-dev (16)
- # cljsrn (2)
- # clojure (208)
- # clojure-berlin (1)
- # clojure-dev (25)
- # clojure-europe (14)
- # clojure-italy (10)
- # clojure-nl (10)
- # clojure-sg (1)
- # clojure-spec (52)
- # clojure-uk (13)
- # clojurescript (53)
- # cursive (7)
- # data-science (7)
- # datomic (4)
- # duct (1)
- # events (10)
- # fulcro (1)
- # graphql (5)
- # jobs (2)
- # kaocha (13)
- # leiningen (6)
- # off-topic (17)
- # pathom (4)
- # quil (6)
- # re-frame (52)
- # reagent (12)
- # reitit (3)
- # shadow-cljs (97)
- # spacemacs (10)
- # sql (39)
- # tools-deps (18)
- # uncomplicate (1)
- # xtdb (1)
I'm trying to get nested subscriptions to work and didn't want to name everything all the way down the tree. Given this example I could make subscriptions for [::field-login :email]
that just seems inefficient.
I use namespaces for that, instead of using filesystem-based keywords (i.e. instead of ::login, etc). So for example I have :db/forms which is a map to all my app’s forms (:forms db), then I have a login form at :forms/login-form, then my username field is :login-form/username, and so on.
But then you're making subscriptions for every field on every form?
Yes, but that has certain advantages, because it isolates the fields from each other, so that when you type in one, it doesn’t re-render the others.
Alternately, you could probably make a function that would take a nested map of fields, and auto-generate the subscriptions using a similar naming scheme. reg-sub
is just a function.
I’ve never actually done that because I like writing out the subscriptions as a form of “executable documentation.”
I had made a simple form, now I'm adding new ones, and its getting hard to read.
It’s a little boiler-platey, but I’ve been burned by too much “magic” code not to have a strong preference for explicit declarations for things.
My thought was, I have a view that is a login form. It know's its a login form. Why does it have to subscribe to [:login-email-value]
instead of just [:email-value]
.
I'm a bit confused by your nested namespaces...I thought you could only go 1 level deep like
{:login-form/fields {:pass "" ...}
:new-form/fields {:pass "" ...}}
You mean in your app-db? No, you can nest things arbitrarily deeply.
You might be interested in a talk I did last conj https://www.youtube.com/watch?v=JCY_cHzklRs&list=PLZdCLR02grLpMkEBXT22FTaJYxB92i3V3&index=11
I have a certain personal philosophy of how I like to write re-frame apps, and I discussed it a fair amount in the talk. It’s not scripture or anything, but it might be useful to some people.
I know I can nest maps, but I can't nest namespaces like :forms/login-form/username
The advantage of using names like :login-form/email
is that it lets you also have a :refer-a-friend-form/email
etc without conflict, which is important because you can subscribe to any subscription from anywhere in your app.
@manutter51, amazing content. Thank you!
Thank you! 🙂
Ironically I’m sitting here wearing the exact same T-shirt today too
Well, this particular arrangement is really good for GUI-type stuff. Once you get into the server side of things, it’s not quite the same fit (much as I wish it were).
Yeah for front end stuff it’s great.
Well, the alternative is Fulcro, which does a lot more in terms of building a robust, well-connected back-to-front application, at the cost of an increased learning curve. People like it and use it for some pretty sophisticated stuff, and it evolved out of Om, so it’s got a great pedigree. So far I haven’t encountered any situation where I wouldn’t prefer re-frame though.
Also...Thanks for sharing that talk. It made what you were saying clear. Namespaces for subscriptions and events, but a simple nested structure for the app-db. That's what was confusing me.
The one rough spot is that sometimes you want to access the value of a subscription from inside an event handler, and that’s generally tricky to do, because of how subscriptions work.
If I’m wrong, please correct me.
app-db is a clojure data structure.
Subscribes
are just a fetcher functions
for the DB
.
I think, every Subscribes
you have defined as a stand-alone pure functions.
You can test them, you can use them in the Events
or Subscriptions
you have.
Is this mental model wrong ?
Subscriptions can’t be used in events, but you can chain them as you did before to get a nested value in a subscription
@scknkkrer There’s some subtleties in how subscriptions are implemented that makes them not play nicely inside event handlers. Subscriptions are more than just fetchers, they’re fetchers that trigger your component to re-render whenever the value changes. Event handlers aren’t components, and don’t have anything to render, so you can see how some things might go astray there.
Or actually, there’s a re-frame FAQ that goes into more detail, and points to a 3rd party library you can use to pull subscriptions into an event handler. https://github.com/Day8/re-frame/blob/master/docs/FAQs/UseASubscriptionInAnEventHandler.md
In practice, I’ve found that most of the time, I can write a function that does what I need to do, and then have the subscription and the event handler both call the function.
That way you end up with the same value no matter where you start from.
I’ve just finished your video. Amazing! Thank you, sharing the knowledge @manutter51!
Thanks, glad it’s useful!
I was meaning that, creating pure functions
that we can test, manage easily and use them in Subscriptions
and Events
. In both cases, one function to use everywhere. That let’s you end up with maintainable code-base
.
Yeah I agree, that’s the best approach.
I’ve an idea about your presentation topic.
I’m writing a book about Clojurescript
. Not a fan of Writing UI
or Designing UX
but, I know I have to write a chapter about it.
I think I’ll mention you and your ideas. If you let me.
Sure, go ahead
I’m just building on what others have contributed, more than happy to see that process continue
i.e., you need to make a state transition to find out what the state was before the (final) transition?
No, I don't think so. But if you just opened it, there won't be enough information there and you have to fire some event so populate it.
Yea it’s really strange. I put a console.log in my secretary event handler which fires a re-frame event and that logs upon first load but apparent 10x isn’t loaded then and doesn’t sniff that out. Then from there on, it always seems like it’s one state change behind what’s actually going on in the app.
Huh. I don't see such behavior in my projects. Maybe something in your code is interfering with 10x? Or maybe your 10x setup is somehow wrong. I'd try to create the smallest app with 10x and see how that works.