This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-03-24
Channels
- # announcements (26)
- # babashka (1)
- # beginners (174)
- # calva (1)
- # cider (10)
- # clj-kondo (27)
- # cljtogether (1)
- # clojars (8)
- # clojure (57)
- # clojure-australia (1)
- # clojure-czech (2)
- # clojure-europe (40)
- # clojure-germany (15)
- # clojure-nl (3)
- # clojure-serbia (6)
- # clojure-uk (11)
- # clojurescript (30)
- # conjure (2)
- # cursive (8)
- # datalog (16)
- # datomic (29)
- # emacs (33)
- # etaoin (1)
- # events (2)
- # fulcro (81)
- # funcool (2)
- # integrant (3)
- # jobs (2)
- # joker (2)
- # kaocha (15)
- # lsp (19)
- # malli (8)
- # membrane (1)
- # off-topic (57)
- # pathom (2)
- # reitit (10)
- # releases (1)
- # remote-jobs (2)
- # reveal (5)
- # shadow-cljs (14)
- # sql (11)
- # tools-deps (8)
- # vim (3)
I’m getting an error when composing routers. I’m following this structure here https://book.fulcrologic.com/#_routers
ERROR [com.fulcrologic.fulcro.routing.dynamic-routing:684] - You are routing to a router :router/SettingsRouter whose state was not composed into the app from root. Please check your :initial-state.
Also make sure to use the latest Fulcro
What am I doing wrong?
How do I compose from root when dealing with nested routers?
I need to call dr/initialize! on mount.
Clojure 3.4.20 I’m getting an error with dynamic router target
ERROR [com.fulcrologic.fulcro.components:874] - Props passed to my.fancy.component/ComponentRoot are of the type PersistentVector instead of a map. Perhaps you meant to `map` the component over the props?
What it says :-) Props must be a map. Why are you passing in a vector? Hard to help without seeing the code.
I’m not pass props to the target? The docs state “The initial state parameters passed to such a router are forwarded to the first listed router target (if it has initial state).” This is the code
(defsc Target [this props]
{:query [:ui/value]
:ident (fn [] [:component/id ::target])
:initial-state {}
:route-segment ["target"]}
(div {} "Target"))
(defsc Target2 [this props]
{:query [:ui/value]
:ident (fn [] [:component/id ::target2])
:initial-state {}
:route-segment ["target2"]}
(div {} "Target2"))
(defrouter Router [this {:keys [route-factory route-props]}]
{:always-render-body? true
:router-targets [Target Target2]}
(when route-factory
(route-factory route-props)))
(def ui-router (comp/factory Router))
(defsc RootComponent [this {:ui/keys [router]}]
{:query (fn [] [{:ui/router (comp/get-query Router)}
(uism/asm-ident ::Router)])
:initial-state (fn [_] {:ui/router {}})}
(div {}
(ul
(li
(button {:onClick #(dr/change-route! this ["target"])} "Target"))
(li
(button {:onClick #(dr/change-route! this ["target2"])} "Target2"))
(li
(div {} "In")
(ui-router router)))))
3.4.20
Doesn’t do it in 3.4.16
Trying 3.4.19…
Occurs in 3.4.19
Something changed between 17 and 18.
@U0522TWDA Looks like you added logging for this in 17. https://github.com/fulcrologic/fulcro/commit/0bf8e61335be6fb50bc3c095de20e4e980863019
So what am I doing wrong in the above?
@U0522TWDA Would really appreciate if you give the code example above a quick look. It looks perfectly fine to me, so I’m not sure why I’m getting that error.
> I’m not pass props to the target
Of course you pass props to the target router The problem is that you are passing it a vector instead of map. So look at the data you have. Why is it a vector? What is in it?
Also, have you tried fulcro-troubleshooting?
Can you replicate the warning with the code you posted above?!
Yes. I get that error with that code.
your error says "ComponentRoot" but that is not in your code?! If it is the root component having issues, how did you register it with Fulcro?!
I renamed the components to simplify the original code but I still get that error. Do you get an error if you run that code? It’s basically the same code as from the book.
I can’t simplify that code anymore as an example router.
According to the error, the root component is the problem, not the router. Can you use the instructions here https://blog.jakubholy.net/2020/troubleshooting-fulcro/ for db->tree to see what the root props are? You can also js/console.log the root props
Your code snippet is missing your fulcro-app and it's initialization
I pasted it into the example.ui ns of fulcro-rad-demo, renamed root component to Root, and fixed imports. Seems to work, do not see this warning you have.
I have the initialization code outside of the snippit. I think the issue is that I’m using a union query in a function query in my RootComponent. Function queries don’t support unions.
It’s strange. The router-props are an ident [:component/id :ns/component] to the target. Should they be a map? @U0CKQ19AQ do you have any idea on how I can debug this further?
(defrouter AuthenticatedRouter [this {:keys [route-factory route-props]}]
{:always-render-body? true
:router-targets [DashboardRoot CompanyRoot PersonRoot InvestorRoot]}
(when route-factory
(do
(log/spy route-props)
(route-factory route-props))))
(def ui-authenticated-router (comp/factory AuthenticatedRouter))
The route-props are an ident.And the error is
timbre_support.cljs:80 ERROR [com.fulcrologic.fulcro.components:874] - Props passed to fierce.pyxis.dashboard.ui/DashboardRoot are of the type PersistentVector instead of a map. Perhaps you meant to `map` the component over the props?
(defsc AuthenticatedRoot [this {::keys [router]
:ui/keys [sidebar mobile-sidebar]}]
{:query [::auth-root
{:ui/sidebar (comp/get-query sidebar/Sidebar)}
{:ui/mobile-sidebar (comp/get-query sidebar/MobileSidebar)}
{::router (comp/get-query router/AuthenticatedRouter)}
(uism/asm-ident ::router/AuthenticatedRouter)]
:ident (fn [] [:component/id ::auth-root])
:initial-state (fn [_] {:ui/sidebar {:ui/sub-sidebars [(dashboard-sidebar-items)
(discover-sidebar-items)
(account-sidebar-items)]
:ui/account (comp/get-initial-state account-ui/AccountRoot)}
:ui/mobile-sidebar {:ui/items mobile-main-sidebar
::account/name "Kathrin Mutinelli"
::account/profile-image-url "/images/kathrin-mutinelli.jpg"
::organisation/name "Stratico"
:ui/dropdown-open? false
:ui/open? false}
::router {}})}
(log/info router)
(let [active-route (some-> (dr/current-route this this) first keyword)]
(div {:className "h-screen flex overflow-hidden bg-white"}
(sidebar/mobile-sidebar (assoc mobile-sidebar :ui/active-route active-route))
(sidebar/sidebar (assoc sidebar :ui/active-route active-route))
(router/ui-authenticated-router router))))
(def ui-authenticated-root (comp/factory AuthenticatedRoot))
That logs the router correctly, but when it passes the props through the router as route-props, it’s an ident.
I don’t think it’s working at all. The logging was added 17
Would I expect an error if it was working? Why would a route target receive an ident rather than props. That doesn’t sound correct.
Routing works, but I get that error on every route change.
@U0CKQ19AQ Here it is https://gist.github.com/stuartrexking/89e92a917c36ad75cabc1b80be7d8bdc
It’s the authenticated flow that’s the problem.
I’ve pulled those components from various namespaces and was trying different things. I don’t have it in my actual code. The gist now reflects that.
Also, that component should prob have an ident, though technically not required. I’m guessing your extra arg to get-query is the problem
It’s not the problem.
Well, I’ve removed it and I still get the error.
you’re using fn for initial state, but you’re using the magic notation…that won’t work
Looking..
you have to call get-initial-state
just like get-query
if you’re using a fn form for initial state
Rage Emoji.
Thanks Tony. Really appreciate it.
Just working through it but it looks like it.
If the initial-state was wrong then the client DB content was wrong, which
(let [state (app/current-state APP)]
(com.fulcrologic.fulcro.algorithms.denormalize/db->tree
(comp/get-query Root) ; or any component
;; Starting entity, state itself for Root
;; otherwise st. like (get-in state-map [:thing/id 1]):
state
state))
would have shown you, now? Also fulcro-troubleshooting might have warned you about missing data in the client DB?It’s easier to analyze that with Inspect DB Explorer, since that lets you click down the exact path from root you’re looking at
my.fancy.component/ComponentRoot is a target
Any ideas?
Hi. I am using form-save*
without using defsc-form
. What is the proper format for to-one and to-many data elements? Is each element an ident?
The answer is yes. Now, how do I insert a new datom in Datomic? I am getting the following error:
:db.error/not-an-entity Unable to resolve entity: [:job/id #uuid "35994e32-533e-4fa1-9acd-292773a6bf70"] in datom [[:job/id #uuid "35994e32-533e-4fa1-9acd-292773a6bf70"] :job/location [:address/id #uuid "ffffffff-ffff-ffff-ffff-000000000300"]]
cognitect.anomalies/category: :cognitect.anomalies/incorrect
cognitect.anomalies/message: "Unable to resolve entity: [:job/id #uuid \"35994e32-533e-4fa1-9acd-292773a6bf70\"] in datom [[:job/id #uuid \"35994e32-533e-4fa1-9acd-292773a6bf70\"] :job/location [:address/id #uuid \"ffffffff-ffff-ffff-ffff-000000000300\"]]"
datom: [[:job/id #uuid "35994e32-533e-4fa1-9acd-292773a6bf70"]
:job/location
[:address/id #uuid "ffffffff-ffff-ffff-ffff-000000000300"]]
db/error: :db.error/not-an-entity
entity: [:job/id #uuid "35994e32-533e-4fa1-9acd-292773a6bf70"]
I think the error is caused by the fact that ]:job/id #uuid"..."]
does not exist in the database yet.Are you inserting an entity and a dependent entity in one transaction and D doesn't understand you have both? I guess I can only refer you to Datomic docs. Or look what the RAD datomic save middleware does..
I am creating a new entity and then inserting dependent entities. I guess I need two calls to form-save*
, one for the key and one for the remaining fieilds...
I’m calling transact!
inside of a initLocalState
declaration that doesn’t seem to be firing the mutation or erroring in any obvious way. I assume there’s a subtle binding issue with the this
inside of initLocalState
? any ideas what I might be doing wrong?
how are you passing this? initLocalState takes a function where the first parameter is this
. If you try to pass it the this
from the component definition it won’t work (I tripped over that)
I mean this
is rebound inside of initLocalState, no? so it would be referring to that this
I think it's more a matter of that function not having access to the outer "component or app thing". So you need to use the reference passed as the parameter to the function (eg this)
you can use it in normal lifecycle methods…but initLocalState is sort of mixed into the low-level js constructor.
I/O, in general, should not, IMO, be tied to component lifecycle, either. Your data model and logic should drive the UI, not the other way around (the exception being a user-event which is obviously given to you from the UI). When you couple your data lifecycle with your UI component lifecycle you’re asking for trouble (or at least a lot of I/O you don’t need).
So, for example, a UI event triggers a route change. A route change calls will-enter (not a UI lifecycle, but a routing lifecycle…subtle but important difference). That, in turn, could trigger something on a UISM that is managing the overall mechanisms of your UI. This is basically how RAD does it: a form is just UI and event triggering on a UISM, where the overall life of the form is managed in logic/data.
Another way of saying it: tie your transactions and I/O to user driven things whenever possible. The user activated a route is different than some component on that route “appeared”.
just realized I never responded to this. thanks @U01DH13SK8E for the help trying to diagnose and @U0CKQ19AQ for the detailed, super informative response – really can’t thank you enough for the time you’ve put into building and maintaining fulcro