Fork me on GitHub

Has anyone written about best-practices or common and useful design patterns when creating apps with Fulcro or Pathom -- and I mean beyond the excellent and existing developer's guides.


For instance, in Wilker's most recent conj talk he nudges people to push computations such as predicates to a defresolver, instead of doing them on the client. In general, I'm looking for some strong-opinions-held-weakly that will help bootstrap a team unaccustomed to working with either library


I’m updating the developer’s guide @uwo for Fulcro 3. That should help quite a bit. Pathom is the official back-end now, and I’ll update the examples and such to use better practices. I will probably replace the “Parsing” chapter with something about modelling things with Pathom. Of course, there’s Pathom’s User Guide as well. On the Fulcro side of things, one of the main recommendations is to use entity-speicifc ID keys for entities, and use that key as that table name:

(defsc Account [this props]
  {:query [:account/id ...]
   :ident (fn [] [:account/id (:account/id props)]}   ; in Fulcro 3 you can just say ":ident :account/id" to mean this

🙏 4

so that the ident of account 3 would be [:account/id 3]


The reason for this recommendation is that it means your pathom resolvers can already respond to ident-joins from the front-end when they have an input of :account/id


(defresolver account-resolver [env {:account/keys [id]}]
  {::pc/input #{:account/id}
   ::pc/output [:account/name]}


That resolver knows how to deal with (df/load this [:account/id 1] Account)


(which is just the query [{[:account/id 1] [:account/id :account/name ...]}])


and since (get-ident this) for some instance would return such an ident, it generalizes a number of data fetch tasks


I think a lot of us are still pretty new to modeling our domains with name-spaced keywords and graph-based entities…from a design perspective, I see the following Pathom features as “critical to know” to help you understand how to model things: 1. Flatten things where possible. The idea here is that it should be possible to model to-one relations “on top of” the link. E.g. address might be a separate entity, but if there is only one on an account, make it resolve at the account level (e.g. via :account/id). :address/id and :account/id can live in the same map, so you still have full CRUD ability). 2. Understand pathom placeholders ( Placeholders do the opposite of (1). They let you invent new edges in your graph. This is useful when your server data graph is flat, but your UI is nested. You can just ad-hoc create an edge that the resolvers will understand. (@wilkerlucio your docs are missing an actual example of usage here!) 3. Understand how Pathom connects the dots. Understand that asking for :some/prop means Pathom looks in the current “context” to see if anything it currently has (like :account/id) can be used as an input to a resolver that returns :some/prop.

🙏 4

I’m probably forgetting some important bits, but the “expand/collapse” features of 1 and 2 are potentially overlooked, and I think they are important.


on that note, might be nice to have dirty-fields in the form-state stuff provide something like {[:account/id xxx] {:field {:before 1 :after 2}}, instead of just the xxx as it helps keeping things straight on the server if there are subforms, etc


Is there any way to create like a global hook, for the new dynamic routing stuff. Basically, I’ve got stuff working fine with HTML routing -> fulcro routing, but I also want to set the current URL if say change-route is called


@eoliphant not sure what you’re saying about form-state, isn’t what you suggested already supported by form-state?


the dynamic routing stuff does not have a built in story for HTML5 url-routing


but it should be pretty easy to add it


why not make your own change-route function that updates the URL and calls change route?


you can compute the new URL based on the state of the dynamic routers in your app


Hey. Away from my computer, but today if memory serves, the "diff map" has something like {123 {...}}


Yeah, I guess the wrapper makes sense, my current stuff is already handling the "click a link, call change route" stuff. Will give that a whirl


I’m pretty sure the diff is key’d by ident.


Yeah, i’d not looked at it for a bit, I misremembered my problem, it was getting from client/fulcro idents foo/by-id xxx to the corresponding ref on the server foo/id xx which i’d worked around by starting to use a consistent mapping of my ‘typing’ key on the server to the ident/table-name on theclient


it is keyed by ident