Fork me on GitHub

Why does :initLocalState in defsc need this and props in its arglist when they are already in defsc's arglist? And why :query and :ident don't need to have them in their arglists? I'm curious about the inconsistency... is there a reason?


Just syntactic sugar for convenience on ident, query, and initial-state. Everything else must conform to what is needed by react (or whatever else uses them). Earlier versions did try to include this in some of the lifecycle, but it led to it being much harder to remember and reason about. The only ones that are special now are the three Fulcro-specific ones. Anything else is “just data”

👍 6

AFAIK it is because that is basically a direct hook into react, and fulcro can't put those other args in scope. But I could be wrong.

Jakub Holý (HolyJak)06:06:17

Don't be afraid to study the code :) It can be overwhelming at start but may pay off later... Of course it is a valid question why "defsc causes an ident lamda to "close over" the defsc argument list" in the case of :ident and not some other cases. Knowing Tony I'm sure there are some good reasons for that. When you read it seems to really make sense to pass the arguments explicitly as they differ across the life cycle hooks and so that they can be consistent with each other and the React docs

👍 6

I have a weired bug in one of my input fields. I am using rad form, with a custom renderer. When I type in the input field, after the first keystroke, the focus is lost. In the transaction tab I see the attribute change event of the state machine, but I dont have any custom code for this event, its the default state machine for this event.

Jakub Holý (HolyJak)08:06:39

Could it be the common issue with React and the browser fighting for control? There is a new feature in Fulcro you can enable to use raw inputs or something like that, perhaps that would help? Tony had a video about it a while back... => use transact!! Also there: > You can technically improve the performance of this (very slightly) by telling Fulcro that you no longer want the dom/input to be a wrapped input by setting a compiler option, but beginners should not bother with this. Nothing there mentions lost focus so it can be unrelated...


thanks, found the bug. it was the way <i was generating the key for the dom enclosing the input element. bcoz it was not able to find it when rerendered onChange, so the focus was getting lost.

🎉 3

however a related concern, it seems on every onChange, the whole form gets rerendered, how do we optimize that ?

Jakub Holý (HolyJak)11:06:07

That is weird. Do you use the multiroot renderer? And does it actually matter that it is re-rendered?


@UMA62JW4W I’m not suer where all I’ve discussed rendering…but the default renderer is a “render from root”. There are options


If each field is a component (with an ident) then you could use :only-refresh


I am not really sure how to use the file-upload functionality (the one from Fulcro, not from RAD) together with form-state. Do I save the image in the normal, actual field using m/set-value!? And where does the file-upload/attach-uploads call go when I also use fs/dirty-fields?


Ahh, nevermind, I solved it by looking at the Fulcro code. Impressively straightforward. 🙂


Hi! We’re using fulcro 2.8.13 with incubator 0.0.30. We’re getting hung up trying to perform a pessimistic mutation that uploads a Thing to S3 using a custom remote; the upload happens correctly, but the response is not being normalized under the Thing ID as we’d expect. The component representing an uploadable thing…

(h/defc Thing
  [this props]
  {:ident :thing/id
   :query [:thing/id
  (when upload-url upload-url))
There’s a ThingManager component with this transaction call tied to a file input. It would seem that the returning is sufficient to normalize the response under the given Thing’s id…
(fpm/ptransact! this `[(our/upload-thing
                         ~{:thing/id active-id
                           :fulcro.incubator.pessimistic-mutations/returning Thing})])
This is the custom remote returning a response we’d expect to be normalized under the given Thing id.
(defn s3-upload-network []
    (fn [this edn ok error]
      (let [{:thing/keys [id upload-url]} (-> edn fp/query->ast :children first :params)]
            (let [response (<!p <perform-s3-upload>)]
              (ok {:upload/network-response response
                   :thing/id id}))
            (catch :default e
              (error {:upload/network-response e
                      :thing/id id}))))))))
What happens instead is the :upload/network-response key appears at the top level of the app DB, and the :thing/id table is empty. It feels like the merge is sort of working, but not fully, and not normalized by the proper Thing ident.


hi, is there any standard advice for how to keep clients in sync when they are concurrently mutating in a subgraph, let's say under an instance of the component Document? The simple but probably stupid way to do it that i can immediately think of is to hook each client up to a websocket, have the server broadcast a :document/id when there has been a mutation inside it, and have clients immediately load the document again, but I feel like there must be a better way


@lgessler I have the same question. I remember Gmail uses long polling instead of websocket, IMHO not a better solution but perhaps supports more outdated browsers curious if fulcro has a idiomatic solution for either

👍 3

haha i didn't know about long polling, that's a cool hack... might make sense for my application

Jakub Holý (HolyJak)11:06:06

I think the WS implementation used by Fulcro falls back to polling if WS not supported