Fork me on GitHub

I'm getting the following errors while trying to build workspaces from the Fulcro template:

Jakub Holý (HolyJak)09:01:29

Running npx shadow-cljs watch workspaces on latest Fulcro develop ( works just fine

Jakub Holý (HolyJak)09:01:46

Ah, sorry, you are talking about template

Jakub Holý (HolyJak)09:01:59

Hm, running the same on latest fulcro-template master (736111f) works just fine as well


Thanks. I updated dependencies and it's compiling now.


hello Fulcro lovers, it’s possible to have random uuid ident? I got nil on db/id

Jakub Holý (HolyJak)10:01:32

I am not sure where the random-uuid function comes from but with (rand-int 100) it works for me. Perhaps your initial state and query is not composed correctly to the root? If that is so than the whole props would be nil Can you check that? As always, start by checking client db data - is it as expected or not? Refer to steps 3 and 3


Thanks @holyjak for your answer. It’s true, I’m not connected the state of the BaseButton to the Root . But the BaseButton is just an UI element who manage an hover state. Maybe I’m missing something but why BaseButtonshould be connected to the Root to manage his own state?

Jakub Holý (HolyJak)11:01:51

See the figure under to understand how props get to components in Fulcro. And from : > Initial state must be composed into the parent’s in the same way as queries do, using comp/get-initial-state. The thing is that "why BaseButton should be connected to the Root to manage his own state?" is mislead. In Fulcro, NO component manages its own state - Fulcro does store and deliver state to all components, through the Root. (With the exception of component local state, which is React thing we mostly do not care about.) This is a fundamental concept in fulcro. I hope that the sections pointed to above clarify it. If not, I will be happy to help make it clearer. In effect you need st. like this in your root:

(defsc Root [this props]
  {:query [{:bb (comp/get-query BaseButton)} ...]
   :initial-state {:bb {} ...}}
    ((comp/factory BaseButton) (:bb props)) ..))


Thanks for your answer again. Actually I thought simple UI components didn’t need to be added to Root. The BaseButton is a low level component used to create higher level components like PrimaryButton. It seems complicated to me to manage the query for a hover state for a component that will potentially be located low in the dom tree and in several instances.


Ok! After a brainstorming with myself 😅 I have a code that works @holyjak Does that look right to you?

Jakub Holý (HolyJak)15:01:51

Yes, per se. But normally you don't model low level components as stateful fulcro components. Eg RAD demo uses button components from semantic UI. If you build them yourself then you can make them as UI-only components, without query or ident. We +- use stateful defsc to model components that represent data entities (as all examples in the Dev Guide do).

Jakub Holý (HolyJak)15:01:39

Manage low level state that is only relevant to the momentary state of the button using component local state. Storing hover? in the client DB doesn't make much sense to me. (contrary to things such as "is this form fields being edited?") On that note, you could have a look how RAD forms are implemented. The form has a query an ident but no component inside it - such as the form fields, text areas, buttons - does.


I absolutely agree with you. Storing the hover state in the client DB doesn’t make sense but I don’t know where to store this state. Does the defsc have a local state?


Maybe the method initLocalState of React?

👍 1

Yes! thank you very much @holyjak


Nice! I will update my gist with initLocalState Thanks @holyjak

👍 1

@holyjak I've been looking at (the initial state of Root8), the app state, fulcro book and the minimalistic tutorial… and I just can't figure out that how does the app state get :menu [:component/id]. I had the impression that initial state also needs to be composed, but it's not happening here. The load doesn't write to :menu either. What am I missing?


Ah, yes. Thank you!


Gah, read the template mode description again, and still don't get it. :initial-state {:menu {}}} should convert to :menu (comp/get-initial-state Menu {}) but that should be just empty map. I'll go read some source code

Jakub Holý (HolyJak)15:01:24

Ah, sorry, I see. Look very carefully at the value of :menu What is it? Tip: use Fulcro DB Explorer to look at it


Well, I didn't use the explorer, but did check it on the repl, as I mentioned in the original post: it's the ident of the Menu component


And via that ident the Menu gets then the cities. That makes sense. I just can't figure out how does the ident get into :menu of the db


I thought it's the initial state, but maybe that's just a red herring

Jakub Holý (HolyJak)17:01:07

Exactly! It is an ident! What does it point to? An empty {} ! So instead of seeing :menu {} as you expected, there is :menu -> [:component/id :Menu] -? {} . IF you change the menu component and remove its ident then you will see what you expected. But since it has an ident, Fulcro normalizes its data - even if the data is empty in this case. Does this make sense?


Well, I mean the feature makes sense, but I cannot figure out where this was documented, or even where it happens in the code


I was surprised about it, and usually that means that I probably have some larger misunderstanding that I would need to solve to avoid future mistakes

Jakub Holý (HolyJak)18:01:37

First paragraph under > The data will be normalized based on idents and stored into the client DB


I read that part of the documentation couple of times again, and yeah, it's there. Especially the example, of course. Let's see if I understand the code


Nope, totally not


But I need to start looking at meta more when I see what's what


@holyjak Thanks for the patience, I think this will be pretty crucial in the future when shaping the connections

👍 1
Jakub Holý (HolyJak)18:01:16

Don't worry, I struggle to understand the normalization code as well, and I have studied and documented it recently 😅 What do you mean by "meta" ??


I mean that Fulcro seems to now and then put pretty relevant things in the meta of the stuff it returns, and I need to get a habit of checking that too to have a clue what it might be doing and how

Jakub Holý (HolyJak)09:01:59

Yeah, that is what we explore in 3.5 here The only thing I know that uses meta is query so that fulcro can track its parts back to their components and thus normalize.

Jakub Holý (HolyJak)09:01:29

Is it clear to you now wht the :menu value is an ident or not?

Jakub Holý (HolyJak)09:01:43

It is a while since I watched so I do not remember it but perhaps it can help clarify things?


I had in fact watched that video again right before, but I still didn't anticipate that initial-state gets changed like that too. But yes, thinking that initial state is loaded in the same way that load!ed or merge!ed data is a working mental model

👍 1

I had a feeling that there's important info in the videos that might not be in the fulcro book, so I started watching the way I had seen again and then the rest. Initial state normalization is also at but just for couple of seconds, pretty ease to just miss that happening