Fork me on GitHub

@tony.kay Great talk, enjoyed it, thank you! I’ve been thinking about events vs. mutations for a bit, but frankly fail to see how they are different in re-frame vs. fulcro perspective: mutations are also just data which can be dispatched from anywhere. In general, you may have multiple event listeners, and that would be the distinction, but AFAIK it’s not the case with re-frame.


Also JFYI Cursive can navigate to multimethod declaration (aka event handler) by keyword (aka event name) in re-frame context. I don’t really see how that’s much different from custom defmutation macro: IDE should be able to resolve it as def + understand all the extra syntax anyway, seems like the difference is only in symbol vs. keyword.


You’re looking at it from the calling perspective. Event systems allow you to “join in” from an arbitrary code point as an observer, making it hard to reason about the system in the large. A function call, sendEvent, or whatever kind of request to “dispatch” that is constructed from call point through to execution point is “walkable” in code. So in that sense any kind of “send event” that is not joinable externally is roughly identical (again depending on tools support for navigation). It’s the “I’m going to start observing and side effecting based on some event” that gets you into complexity that isn’t easy to follow.


In terms of Re-frame: I’m no expert there, but it looks to me like you can declare a data dependency on some other thing that gets auto-resolved. This is an event observer pattern. I can pepper those all over the code, and now it is very hard to reason about “when X changes, what happens?“. That’s all I mean.


In Fulcro, without extensions, you don’t have that. You have to forward-feed data through a call chain, even if it is a “mutation as data” call chain. It is always dispatched and multiplexed manually. This is both a pro and a con, which I talk about in a later episode 🙂


Yes, I see your point, observer pattern is what I meant by "multiple event listeners". I've just double-checked and you can't declare more than one event handler in re-frame, so Fulcro & re-frame seem to have similar event/mutation semantics. Moreover, ident joins and link queries in Fulcro are essentially re-frame subscriptions: you can subscribe to any part of the db from any component. That's rather anti-pattern, yes, but you can 🙂


Is there a way I can follow that podcast without having to create a soundcloud account?


you’d have to ask soundcloud 🙂 I have no idea. I know Jacek will be posting updates, so you could find and follow him instead.


I have a little problem with making reusable components with defsc... How do I introduce new, component-local query variables? I tried to just add it to the query as a :ui/... the way I usually do, but that fails when I use comp/factory on it and then instantiate it. No matter what I have in :initial-state, it will just always be missing from the props map.


If you don’t make a proper join on this component from the parent, then :initial-state won’t be used: it’s used only on the first app render by recursively walking the joins from the root. What you’re probably looking for is either React local state (:initLocalState defsc attr + comp/get-state, comp/update-state!) or React hooks.


Ah yes, that seems to work! Thanks! I already was trying some stuff with :initLocalState, but I hadn't fully figured it out

🎉 3

@tony.kay I have submitted for patch to allow vars in ro/columns. Please review the below -


I’m not sure that’s what I’d want. The macro does various things with that, and a var is a runtime thing, not a compile-time thing. I think requiring a vector of symbols is what I want to stick with for now. I could be convinced otherwise, but as soon as I “require less” there’s no going back.


in the ::fo/attributes, it allows a var. now I have the same columns which I am using for the form and the report. so it seems inconsistent that in one place I can specify the columns and in another I have to type them out.


also I can just reference the attributes var defined in the model file, which is a vector of all the attributes.


@tony.kay any word on this one ? Its just a useful thing to have when one can link up generated attributes. I have a macro which is generating for me all the defattrs given a list of string column names. I then just refrence this generated vector in my code. If the above ability was not available to me, then I would have to manually copy/paste the column names. Now this could get out of sync, because my source of truth is the list of string column names which I use for creating my attributes.


Hey, I don’t think our little study group is able to meet this week sorry, (unless others want to do so without me =)…). A few things have resulted in my inability to set up something today >_<… I’ll do one next week if people are still interested =)…


Enjoyed the podcast

☝️ 24

Glad to hear it, thanks!


When I am setting the ao/default-value (congnitect.transit/bigdec 0)for an attribute, I get the Tag "f" cannot be encoded as string error in the console (the app crashes). Where is the tag f value coming from ? Where should I look to debug it ?


@murtaza52 tags are part of the encoded transit type


f is the marker for bigdecimals


I think you should be using math ns for that default value, though


thanks, that resolved it.


Tony, thanks for designing such an extensible system. Just realized how simple reagent rendering support is:

(defonce SPA
    {:render-middleware (fn [this render] (r/as-element (render)))
     :render-root!      rdom/render}))

👍 3

yeah I made a video on doing that with reframe as well. I knew we’d start to outgrow some of these things as our understanding and techniques got better. A hybrid of a number of approaches is probably the real sweet spot.

Adrian Smith21:06:29

Any one got any ideas why this might not work? I don't get errors but anything under or including <theme-provider> doesn't render, I have basic react app where test does work (I'm trying to use


I don’t remember, but I think the react factories require props (i.e. at least an empty map). You’re passing a child where you should be passing props


@sfyire (theme-provider {} (badge {} "test")) perhaps?

Adrian Smith21:06:05

lol I was just watching your 16th video randomly and noticed your wrapper needs empty maps too, at the same time just saw your message

Adrian Smith21:06:27

it works thank you


For sure, I watched the video before trying it out : ) the next step is trying this out: