In Fulcro RAD, can anyone help me with disabling (or even making invisible) a subform? The situation is that I want file upload functionality (the subform) to only be available when a particular form attribute is valid. I can already test for this attribute's validity with (attr/valid-value? attribute attrib-value)
. For experimentation purposes I did this from an fo/field-visible?
function on a 'random' scalar attribute. If fo/field-visible?
worked with a ref attribute then I'd be fine.
disclaimer: I’m a complete newbie. My intuition is that the validity of your field should be encoded in the data-model from which the other component pulls this information. Is that so?
Is it reasonable for some UI changes to not go through the transaction system and simply update the DOM without being reflected in the client DB, or is it better to adhere to the practice of tracking all UI state changes as changes to the client DB?
Thanks @tony.kay. I'll lean heavily towards using Fulcro except for the most inconsequential UI changes.
Generally, whether you use fulcro or vanilla JS, you might end up using the DOM as your DB, which inherently corrupts your data/state except you synchronize everything nicely, which is something that proliferates very, very quickly and creates hard to track down bugs.
hacks can be valuable short term. but frameworks like fulcro make it so easy to separate these things so why go there? I guess if you integrate third party code.
The file to be uploaded is a csv file and the attribute that needs to be valid is the headings of that file. I want the user to be required to input valid list of headings (eg./ date,desc,money) before uploading the file becomes possible. This might mean the upload button becomes enabled. I want to develop an intuition for solving these kinds of problems using the mechanics available in Fulcro RAD.
Hello guys, new to fulcro, coming from reagent + re-frame. I've seen Tony Kay's videos, and read some of the other guides/examples and one thing i noticed is that every component is created using the defsc
macro, thus having components with big bodies made of primitive html elements. Is it an anti-pattern/invalid to just use reagent-style functions for stateless components? e.g
(defn label [text]
(dom/div :.label-class text))
It depends. There is no magic Reagant style conversion of functions into classes (the major upside to this is your stack traces are not full of Reagant internals). But you can write a defsc
with no query, ident, etc. to get what you want:
(defsc label [{:keys [text]}]
(dom/div :.label-class text))
…using a defn
as a component is probably not doing what you think it is
Thanks for the clarification
Just don’t forget, you still need to use comp/factory
to create a ui-label
. Again, there is less magic than either Reagent or React with JSX
Hi everyone, I was having a look to https://www.apollographql.com/docs/react/, and they do this “declarative data fetching” thing:
> Declarative data fetching: Write a query and receive data without manually tracking loading states.
I was wondering if something like this could be done for fulcro? The defsc components know their query and its parameters, and they could register to some “I’m going to appear” hook (via component will mount lifecycle, deferred routing, etc). Then fulcro could aggregate all necessary data to fetch, and exclude anything that’s already loaded in the client’s DB (not sure how to handle invalidating cache here). Fulcro could also figure out if we’re requesting an attribute for a specific ident (i.e. We have many components that display [:user/first-name]
, but only one with ident [:user/id 2]
shows the user’s cars [:car/id :car/model]
, and again, ignore it if already present in the client’s DB). All aggregated queries would look like this:
{[:user/id 1] [:user/email :user/role :user/first-name] ...
[:user/id 2] [:user/email :user/role :user/first-name [{:car/id [:car/model]}]] ...
[:item/id 1] [:item/price ...}
And then be auto merged to their corrects client paths (also taken from each defsc’s ident). defsc could have a join in their query on some autoloading namespace (kind of like the forms config join) that give it, say, {:state :loading/failed/completed}
.
For pathom params, they could be in the defsc’s queries (i.e. pagination params) and whenever they change, a new fetch would be triggered.
Auto-fetching should be opt-in, of course. It is nice to have the possibility to fetch the data manually and is a good default behavior.
I just wanted to share some thoughts, I’m very new to fulcro (around 2 weeks of learning) and not sure if this goes against fulcro’s philosophy, if it is even possible and/or would break things 🙂. Could something like this be done for fulcro?this is really cool! I have try out these nc and hooks tools..
To clarify: You still need 2 arguments, ie [_ props]
Fulcro already has built in loading state tracking, but it's opt-in - see the load marker param to load! Fetching in willMount can lead to cascading remote calls - A will mount and loads its data, it renders its child B that will load its data,... Loading the whole relevant subtree for all the child nodes at once eg using dynamic routing and :will-enter will give you much better performance. And works just fine in practice, I haven't felt any need for auto loading.
Btw have you seen https://fulcro-community.github.io/guides/tutorial-minimalist-fulcro/?
This is a pretty interesting idea, one thought of how to go about it is to add a new property to defsc
like ::subscriptions
or whatever name you want, which would be the opt-in parts of the graph that result in remote calls. This could be a data structure like a normal fulcro query but maybe has which remote to use and the caching policy to use. You can then make your own macro that wraps defsc
and handles the details of fetching the data.
Notes on how to wrap defsc can be found in this talk by Wilker:
https://youtu.be/R_XPwi0Kiwk?t=246
Hi @holyjak, thanks for your response 🙂 Yes, I’ve seen it, I think you’re the author, right? Thanks a lot for such a valuable learning resource 😄 Yeah, I read about the cascading issues in the tutorial, and I thought auto-loading could be done without cascading, some work on the backend may be required, to have a bulk query resolver and recursively resolve queries using IDs from previous resolved queries in the same bulk query request. I also have seen the loading tracker state via markers, and this could be used as a join in defsc queries to get the request state, but would be nice to be auto-hooked for bulk query “global” request. My point with this post was not having to write such code. I liked apollo’s declarative data fetch, where you don’t need to think about handling the fetch itself, it just happens and is there for you for you to use in the view. I mean, I’m ok writing such code to manually load the data, but wanted to explore the possibility of having declarative fetching in fulcro, as component’s know all data they need in the UI tree. 🙂
as Jakub mentioned, there are existing pieces in fulcro that should make adding this sort of thing pretty straight forward (the remotes abstraction and load state tracking)
@danvingo Yeah, I figured it should be something easy to do with current fulcro’s building blocks. I’ll try something to go over defsc’s metadata and traverse the UI tree queries and see what happens 🙂 Subscriptions would be nice, but that’s a complete different beast. However, as Tony said in one of his videos, Fulcro is ready for such real-time features to be plugged easily, the hard part is to notify the client when the data changed in a scalable way 😛
Ah, I didn't intend for subscription to imply live updates, just a way to distinguish the parts of the query that you want to result in remote calls
Ah got it, yeah. I think wrapping defsc in a macro is an overkill. I think traversing defsc’s metadata should be doable, I’ll check the video you suggested ❤️
I think wrapping defsc is the way to go, one of the great parts of fulcro is that the component options is an open map, so you can add whatever extensions you want there. Here is an example adding re-frame subscriptions by wrapping defsc and adding a new key, if you want some inspiration: https://github.com/dvingo/fulcro-re-frame-playground/blob/main/src/main/dv/fulcro_re_frame/play/client/fe_macros.clj#L134
Nice! Yeah, I thought it was going to be an open map with data everyone can just use 🙂 — fulcro was created by a clojurist after all 😉 As a second thought, I think you’re right. Maybe I need a macro because I’d need to hook the “I’m going to show” callback (whatever that will be), and for that I’ll need to change the component somewhat. Another option would be to let the user handle such hook, and call a function to register to the global bulk query request that is going to happen.
after writing that I think I prefer letting the user decide when to register his component 😛
or both… 🙂 … anyway, thanks a lot for your input! ❤️
for sure! I'm interested to see what your explorations uncover 🙂