Fork me on GitHub
Jakub Holý (HolyJak)10:06:55

@tony.kay I have a problem where a parent deferred route takes a long time and its child route is resolved earlier. The app still works but it warns that "get-ident was invoked on InventoryReport [the child] with nil props". See the commit message in for more details and the timeline of transactions. My question is, is this a bug in dynamic routing / RAD? Both routers get their :ready! in the correct order (i.e. parent first) but before that there is target-ready [... InventoryReport] , which I assume produces the warning. If this is indeed a 🐛 , I'd be happy to help fix it, if you could point in the right direction... Thank you!


@holyjak could be either, but I’d suspect dynamic router…but the child route should not resolve until the parent is there. Really, I don’t have time to delve into that more deeply. I do not remember off the top of my head much of the internals,…that’s why I wrote a book. I do a lot of diff things. It would take me 20-40mins to look over your code, remember what all is happening internally, etc. All for a warning. I do not have the time. Sorry.

👍 4

Hi @tony.kay! I opened a small pull request against fulcro ( I didn't find any test I could expand to test for this particular problem but was able to test and verify it locally. Eager to hear any recommendations or possible improvements! 🙂


@hannes948 thx. I sent feedback. A slightly better explanation would be appreciated. I maintain a lot of code and don’t have it all “queued up” so to speak


@tony.kay sorry for that, will react shortly


np, thanks for figuring it out to begin with 🙂


3.2.10 is on clojars with the file upload fix @hannes948


@tony.kay wow, that's fast. Thanks a lot!

Björn Ebbinghaus15:06:39

@tony.kay Did you miss to push some commits to your workspaces fork? The project.clj states RC3 but the latest version on clojars is RC4.


The f3 branch is the actual work I think


Ah, I don’t use lein for publish. The pom.xml is updated. I didn’t update the project.clj file


and yes, it is all pushed

Eric Ihli18:06:41

Caused by: Could not locate com/fulcrologic/fulcro/networking/http_remote__init.class, com/fulcrologic/fulcro/networking/http_remote.clj or com/fulcrologic/fulcro/networking/http_remote.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.
Odd thing happened. I was getting this error intermittently when I would try to evaluate the app.application namespace from this part of the book I tried deleting .m2/repository/com/fulcro/ so that I'd get a fresh install. Now I get the error every time I try to run a repl, npx shadow-cljs server or clj.
➜  ezmonic git:(test) ✗ strings /home/eihli/.m2/repository/com/fulcrologic/fulcro/3.0.10/fulcro-3.0.10.jar | grep 'com/fulcrologic/fulcro/networking/http_remote'
The file is there. Ohhhh I think I see. I'm going to type this out anyway so it will get picked up by the chat log archiver and show up in search results for anyone else who sees this error. CLJS files can refer to CLJC files, but CLJC files can't refer to CLJS files. That seems obvious. My file was cljc and http_remote is cljs.

Eric Ihli18:06:00

Speaking of... how are remotes set for server-side rendering? Is it patched onto the initial state that is sent to the client and then hydrated in

Björn Ebbinghaus20:06:15

Remotes are neither something to render nor data for the client db so they are just set when the client is starting


I'm wondering what the smartest place is for authorization checks. First thought was to do it as a pathom middleware.


I thought about that as well today. I ended up adding two remotes, one /auth and one /api and put a ring barrier in between.


So the SPA sends its requests to /api first, and the program then internally uses /auth?


No, session management is exposed via /auth, and the ring barrier does some rudimentary checks if the request is allowed to pass to /api depending on the session/cookie. It doesn't allow me to do per-resolver/mutator authorization (yet) and I am not sure how I would realize that. Maybe I make sure I always need some data from the session so I can resolve or mutate or automatically bail out with an error. I don't have a good concept for that yet.


My main goal was to have something that is easy auditable in the beginning.


(to be more concrete, I set up two remotes in fulcro-app and use the particular end point explicitly (/auth for login, logout, session check) and /api for everything else)


FWIW, I have ended up putting checks in the resolvers themselves.


I thought about that as well, but I am also using RAD forms, which means I wouldn't have control over these


Indices and other meta-information might also be visible. Not that I care too much, but I haven't fully grasped pathom yet what it provides and will provide. 🙂


Yes, I think I will go with that.


I have a question about the design of EQL which I'm not sure this is the right place to discuss. However, I feel EQL is something fulcro users deal with heavily so I think it might be valuable for me to hear your opinions: There are couple of quirks that made me wonder why EQL was designed like it is. Let's take a look at a typical EQL -- the kind of which probably show up in your app hundreds of times

     {:user/projects [:project/id
     {:user/contacts [:user/id]}]
EQL claims to have "the same" shape as the returned data. That's awesome! However, why don't we go a step further? Consider the return value of the above query:
{:user/id #uuid "..."
     :user/name "Fred Mertz"
     :user/email ""
     :user/projects [{:project/id #uuid "..."
                      :project/name "Mertz and Kurtz"
                      :project/start-date #inst "..."
                      :project/end-date #inst "..."
                      :project/completed? true}]
     :user/contacts [{:user/id #uuid "..."}
                     {:user/id #uuid "..."}]}
Why wasn't EQL designed to completely mimic that structure:
{:user/id _
     :user/name _
     :user/email _
     :user/projects [{:project/id _
                      :project/name _
                      :project/start-date _
                      :project/end-date _
                      :project/completed? _}]
     :user/contacts [{:user/id _}]}
Or, if the explicitness of pluarity is not desired here:
{:user/id _
     :user/name _
     :user/email _
     :user/projects {:project/id _
                     :project/name _
                     :project/start-date _
                     :project/end-date _
                     :project/completed? _}
     :user/contacts {:user/id _}}
The immediate benefit is that now I can use the map namespace syntax to make it much more succinct and DRY (and easy on the eye):
#:user{:id _
           :name _
           :email _
           :projects #:project{:id _
                               :name _
                               :start-date _
                               :end-date _
                               :comleted? _}
           :contacts #:user{:id _}}
IMHO many important semantics are much better aligned this way. For example, in a return value, the order of the keys in a level of map should not matter, and there should not be duplicated keys. However, EQL uses an ordered collection (vector) to denote the keys, the semantics of which has a sense of order while ensures no uniqueness. Also, it feels like in EQL maps are used in place of pairs. I understand that Clojure doesn't have a built-in literal for pairs so it makes sense to use maps, but maps seem to be a poor fit for this role -- here they are only allowed to have one key-value pair, and pushes the key into the next level when it should really belong to the outer level. I feel that the ad-hoc-ish design not only misses mathematical simplicity but also make everything unnecessarily complex. If I were to write a function to retrive all root level keys given a EQL (which should have been trivial), the implementation would be a few lines unnecessarily longer since I need to consider those ref-type attributes. If I am using Emacs to manually write a test example given an EQL, I am doing lots of unnecessary work changing brackets into braces and splicing sexp's. That being said, my exposure to Clojure and Datomic/Pathom/Fulcro is limited, and I truly want to hear if there are reasons why EQL was designed the way it is rather than my intuitive version. I apologize my above arguments spiralled into a small rant.