Fork me on GitHub

Perhaps you didn’t compose initial state of this component into the parent all the way to root?


Use Fulcro Inspect DB Explorer. Start at root, click idents…see where it is broken


OR, you didn’t PUT a TagPage into state that has that ID


the ident warning is that you tried to mount it and it’s ID was nil, which means its props were empty


which means your state tree is not right.

Aleksander Rendtslev09:03:08

Hmm, that makes sense. I added the tag page to the router, but at this point I didn't have the node it's referencing in the DB. I'll try doing that

Jakub Holý (HolyJak)11:03:23

You can also give a try to which is intended to help you discover such problems ASAP. Feedback welcome 🙂


Hi all! I inspected fulcro and it seems very appealing to me for various reasons but one thing is still a bit u nclear to me: How do you write the server if other systems than a desktop-app are involved (E.g. mobile apps) where EQL might not be applicable by the client-technology? Do you usually write two ways to talk to the server (for example EQL/Graphql) or go streight a Graphql (or REST) route and not using EQL at all?

Björn Ebbinghaus12:03:36

I think you got something wrong here. Fulcro is a client library.


I guess you're right, I don't see the full picture. Does not fulcro, if you use the http remote for networking by default use transit to send EQL queries to the server where the resolvers for said queries are situated?

Aleksander Rendtslev13:03:55

Fulcro is definitely not just a client library. It’s fullstack. But I wouldn’t use it for scenarios where you don’t have full control over the clients. You could separate out your business logic from your resolvers/mutations and then simply add an api for external clients. I think fulcro is amazing for any client you control (Even mobile. I’m using fulcro and react native to do that). It allows for much faster iteration cycles. But I think it’s generally advisable to keep a separate API for clients that you don’t control, and simply have it call into your business logic as needed. • Fulcro apps (mobile, web, desktop) • Graphql or REST api or none EQL client • Business logic (The two above calls into this part) You could use or just take a cue from how they do their separations. I’m not doing that and I haven’t (I don’t need anything Fulcro can’t provide), but I’ve built projects in similar ways in the past.


Thank you for the elaborate answer! A desktop app together with a React Native app was what I am planning to go for. All clients would be controlled so that wouldnt be a problem. So I guess the Fulcro/GraphQL route sounds promising for that usecase

Aleksander Rendtslev13:03:52

You don’t even need to use Graphql. You should be able to do it all in Fulcro with eql then. React Native and Fulcro has been a very pleasant experience so far.


Oh really? I thought the React-Native story with ClojureScript was still a bit wonky last I checked. Good to hear that its a pleasant journey! I may look into that

Aleksander Rendtslev09:03:53

I haven't hit the issues yet. I was worried about performance and app size but right now the app checks in at 11mb and it's buttery smooth. Probably smaller than other RN apps because I'm less inclined to use libraries (though it's extremely easy to do)

Aleksander Rendtslev09:03:49

And the idea of not writing it in clojure at this point is... Unpleasant


I actually just found the section of pathoms graphQL integration... that may be the simplest route


I’d like to use comp/get-query with a union components to get the type query… am I missing something besides have two versions of the ident fn (one that takes props and one that uses the closed over props in the defsc)?


granted that’s a pretty minor issue 😄


idents go both ways: used to ask what the component’s ident is on things like refresh, and used for normalization. In union case, the parent is used for normalization, and the child is the active thing on screen…thus the need


There’s certainly a macro waiting to be written there, but the EQL nesting of it needs two components, even if you don’t much care about the parent


but perhaps I’m not understanding your question


Sorry, I’m probably not being very clear, it’s such a simple thing probably not worth your time… 🙂

(defsc UnionComponent
  [this props]

   (fn [_]
     {:type1/id [....]})

   (fn []
        (contains? props :type1/id)
        [:type1/id (:type1/id props)])}
(comp/get-query union-ns/UnionComponent)
…returns the whole union query but I’m interested in the concrete query. So I need to do:
(defn get-ident
    (contains? props :type1/id)
    [:type1/id (:type1/id props)]))

(defsc UnionComponent
  [this props]

   (fn [_]
     {:type1/id [....]})

   (fn []
      (get-ident props))}
((first (get-ident props)) (comp/get-query union-ns/UnionComponent))
I thought maybe I was missing something as it’s the first time I’ve used union components


Which is ultimately fed into:

(dnz/db->tree query concrete-props state)


Regardless, I think I’ve obviated the need to manually get the local state tree… I’m refactoring part of an existing application.


I’ve been thinking about the raw components and hooks stuff I’ve been working on (in case you missed it, see and I’ve been tuning up the ideas, and it occurred to me that these are all their own little “sub roots”, and that they could use nsed root db keys for their starting point (the line 42 version doesn’t work well unless you give it initial state, becayse it needs to know an ident to start the mini-tree). So, with that realization, I’m thinking:

(let [current-user (use-tree :application/current-user [:user/id :user/email {:user/settings [:settings/id :settings/marketing?]}]
                       {:load-if-missing? true
                        :load-options normal-load-options})
would be more useful. I’ve already written code that can auto-normalize the above query IF you use the naming convention of a single ID field per level (e.g. :person/id and :settings/id become the ident generators in this example, see nc in raw-components2). Then it occurred to me that load isn’t the only thing you might want to have manage the state of the thing…you might instead want UISM, so, at least for a single actor, it seems like I could make a (use-uism …) in a similar vein where you supply a UISM def, and it triggers an event on that UISM, which in turn does whatever it needs to do (using the code you wrote) to set up state, and returns destructured actor trees:
(let [{:actor/keys [login-form]} (use-uism login-state-machine options)] ...)
These, of course, are all intended to be usable within any (potentially raw) react component.

❤️ 6

I’m terribly busy lately, so if anyone is excited by these and wants to help, pls let me know.


I am trying to figure out how to display long text blocks across multiple lines, with ability to insert line breaks, inside of Fulcro (RAD) views. I’ve tried various ways, including adding ao/style :sulti-line, inserting “\n”, injecting HTML “</br>” and other things into the column-formatter, etc… I’ve Googled “semantic-ui textarea adding line break,” but haven’t gotten anything to work. Does anyone have any ideas on how to best do this? Here was one of my attempts: Many thanks!!! cc @holyjak

(defattr description :vimeo-video/description :string
  {ao/identities #{:vimeo-video/uri}
   ao/style       :multi-line
   ro/column-formatter (fn [_ value]
                         ;(println value)
                         (if value
                           (clojure.string/replace value #"\n" "<br/>")))})

Jakub Holý (HolyJak)18:03:02

Didn't we arrive to that you need to set the right CSS prop on the component for it to respect \n? So just somehow eg give it a particular CSS class (I think there is ao/<something> for it now) to it and define the CSS class with the prop?


I second that; I’ve done this stuff inside a Clojurescript text editor built on textarea; even then it’s just CSS

Jakub Holý (HolyJak)19:03:09

🙏 @tony.kay do you plan to release a new version of RAD? I see there is a couple of (mostly mine and tiny 🙂) commits that have not been released yet...


Thanks for the reminder. Done.

❤️ 3