@holyjak thanks for those…I’d appreciate gathering up a few in the future and submitting one PR 🙂
published changes
defrouter’s body is optional, is a render, and should not side-effect…so confused what you mean
perhaps book has confusing text?
Can rad forms be targeted? person has an address, but allow a button on the person line item that says add address
, which routes you to only the Address
form, and leaves all ui for person out.
Looking at the source makes me think no, but I'm kinda hoping that I'm just missing the support 🙂
@jatkin yes
sorta…depends on what direction the association is modelled
or you can agument save middleware to fix it up
Oh, Gacha. it would need middleware in this case if I understand correctly
If person had a ref to addresses
1. Add a virtual (fake) attr to address as :address/person
2. Send it to the form as initial state
3. In save middleware, capture the fake and rewrite it
Cool, sounds like a plan
you’d make a special instance of address for that, since it would have to declare that as a field
and you’d just hide that field
should work
Cool. Do you keep a list of tips like this anywhere? If not it may be worthwhile to monitor this channel and compile stuff like this from you and others on the channel into a big fqa.
nope
I would love to have more time to document the project, but I don’t 😞
I’ll start watching and compiling stuff like this. I’ll try to tag stuff as I go. Maybe it will be useful :).
I’ll put it in a gh repo
Just putting some feelers out - is there anyone that might be interested in doing a meetup presentation on Fulcro?
🙏:skin-tone-2:
w.r.t? Most likely.
In the process of digging into all the Fulcro materials and would like to share a few thoughts, hopefully helpful to those who are also dipping their toes in Fulcro. Though I've found the videos and the developer guides to be an excellent source of information, the learning curve is very slow at the beginning especially if you do not have prior knowledge on Om Next (not to mention React and GraphQL). However, it is definitely an increasing-returns learning curve when you truly get the point of Fulcro's design. The things that helped me get Fulcro is the Fulcro2 videos which filled in many blanks and guided me to explore Untangled and Om Next. Interestingly, the unlisted and supposedly outdated videos are the most useful. These gems are not easy to find. I only found them while going through loads of Slack chats; these two are my favourites: 1) https://www.youtube.com/watch?v=nlT45ikSEOE&feature=youtu.be&list=PLVi9lDx-4C_Rwb8LUwW4AdjAu-39PHgEE , 2) https://www.youtube.com/watch?v=mT4jJHf929Q&%3Bindex=8&%3Bt=1578s&%3Bab_channel=TonyKay . Until a unified source of Fulcro know-how comes up in the form of new videos or books, learning Fulcro does involve a high upfront investment of time, which I am more than willing to pay, in hope for the long-term benefits. There's so much more to learn and I am just starting to experiment with Fulcro. Look forward to sharing more along the way. P.S. I can watch the videos over and over again, but the sudden loud coughing in a few of the videos may be off-putting to some beginners especially when they are listening intently. This didn't deter me and many others from continuing with the learning, but anyhow, the videos would be literally perfect if the coughing can be edited out. My heartfelt thanks to Tony who is not only an awesome and talented OSS author, but a great and generous teacher!
Thanks for the feedback Alex. Sorry about the audio. I don’t have the time to do everything I’m doing and post-edit videos…those are literally single-take, barely-planned and lightly-outlined attempts at giving people info as quickly as possible. The older videos talk so much about the APIs (that are now out of date) that I hid them to prevent confusion for new users. I agree with you on the second one. I really need to re-make that with updated terminology. I have not watched the first one since I made it, so don’t even remember what is in it…but if you found it that helpful I will consider re-making it (or relisting it if it is up to date enough). If anyone would like to volunteer to post-processes this kind of stuff, I’d be more than happy for the help…or if you just know of an automatic post-processing (like a compression setting on ffmpeg or something) that will make loud noises better, let me know. I cannot afford to re-record an entire video because of a cough 🙂
Thanks @tony.kay for replying. Your videos are absolutely helpful and you are a great teacher! A re-make that combines the information of the above two videos with the updated terminology would be excellent. Until then, a re-listing would be really nice, maybe also re-list a few more gems from old times? 🙂 Though not a video expert, I would like to volunteer to post-process your videos including editing out any loud noises, etc. Let me know anytime when you need any video editing. It'd be my great pleasure to help. As for the old videos, there is only one way to edit them without breaking the urls and removing all the views, comments and stats: that is to use the built-in trim function in Youtube Studio. You can find more details here: https://support.google.com/youtube/answer/9057455?hl=en . This is for your reference only. To save your time, I think leaving the old videos as they are and post-processing any new videos going forward is a good plan. Thank you so much again for taking the time to record all these awesome videos and sharing your knowledge and creation with us.
At https://roamresearch.com/#/app/CommunityFulcro there is > Add a virtual (fake) attr to address as :sale/account Shouldn't it be "".. to Sale ..."? Also, what is a virtual/fake attribute? One that does not have a field in the db?
Yep on both
I hope y'all find this useful. I'll be watching the slack chat for anything that catches my eye. Tag me if you want something specific added. If you want to add material yourself let me know and I'll add you as an editor.
If anyone has some ideas of stuff that's already gone off the chat link it and I'll add it as I can.
See this page first: https://roamresearch.com#/app/CommunityFulcro/page/y0-H3KDlM
Update: the proposed solution of using :ui/ready?
solved the problem
@tony.kay you mentioned that
> Attempt to get an ASM path [..] for a state machine that is not in Fulcro state. ASM ID: <some router component>
is mostly harmless. To fix, you recommended
> You can use app/set-root!
with initialize state, then dr/initialize!
or dr/change-route!
, then app/mount!
with NO initialize state to get rid of most or all of those. Basically: Make sure you’ve explicitly routed to a leaf (target) before mounting.
I have tried that - in my init
fn I have
...
(app/set-root! app mb-ui/Root {:initialize-state? true})
(dr/initialize! app)
(history/install-route-history! app (html5-history))
(setup-RAD)
(dr/change-route! app (dr/path-to mb-ui/Intro)) ; overridden in app's on-mount but this makes sure the root router is initialized
(log/info "App init (almost) dome") ; FIXME rm
(app/mount! app mb-ui/Root "app" {:initialize-state? false})
however the warning did not go away:
> INFO [client:146] - App did mount
> DEBUG [com.fulcrologic.rad.routing.html5-history:93] - ["Pushing route" route params] =>
> WARN [com.fulcrologic.fulcro.ui-state-machines:?] - #error {:message "", :data {}} Attempt to get an ASM path ... ASM ID: :mb.ui/RootRouter
> DEBUG [com.fulcrologic.fulcro.ui-state-machines:?] - Trigger :mb.ui/RootRouter
So it seems to be a timing issue, the rendering starts right before the router UISM gets started.
I suppose the solution is either (1) ignore the warning, it is harmless or (2) add`:ui/ready? false` to the Root
and only switch it to true and start rendering anything after the routing system is ready (I guess I could simply (transact! app [(set-ui-ready)])
at the end of init
since transactions are executed in order and thus this will run after the UISM start transactions issued by dr/initialize!
). Correct? Thank you!@holyjak correct. The transactions are queued in the default tx processing, so there can be transient flickerings and warnings unless you block rendering until your init is done. You could also try the sync tx plugin, which runs all optimistic stuff synchronously…but it is considered of alpha quality since I have not used it heavily.
(though I’ve only seen one reported issue, and I think it is mostly harmless): https://github.com/fulcrologic/fulcro/issues
it’s the only thing “open”…returning false from a remote section causes a problem…I still need to fix that, since in some cases your logic would need to return false there.
thank you!
another thing to say better in the book 🙂
When making a single load!
with :parallel true
I get pending...
in the network tab in Inspect and I get :com.wsscode.pathom/trace
merged into my state.
Without :parallel true
everything works fine. Any clue whats causing this?
Just seen Rich Hickey's announcement about sponsoring open source devs and I instantly thought of Tony. It turns out that Tony is already in the list of those being sponsored from today on https://github.com/orgs/cognitect/sponsoring
Is the display of Diffs in the Transaction tab of Fulcro Inspect (latest chrome plugin, Fulcro 3.4) broken?
When I click a uism/begin transaction, I have to click buttons to load the states before and after. I expect the diffs to get updated therearfter but they still show nil
even though when I expand the before/after state, they do differ (in the :pending-route :path-segment
). Is it a 🐛 ?
News to me 😄
Nice. That’s really cool.
@mroerni could be a bug in inspect reporting from Fulcro itself. Does the load work correctly otherwise? (e.g. just an inspect issue?)
Yes. It works correctly.
@tony.kay I'm trying to follow the RAD middleware suggestion you talked about earlier, but I'm not sure what kind of transformation I need to do in the middleware, this is what I tried:
(defn account-id-dance [params]
(update params ::form/delta
(fn [delta]
(mc/map-vals
(fn [vals]
(reduce-kv
(fn [out k v]
(if (= k :some-custom-entity/account-id)
(assoc out :account/_reverse_link
{:before nil
:after [{:account/id (or (:after v)
(:before v))}]})
(assoc out k v)))
{}
vals))
delta))))
but the format was a guess in my part, how it should go?
FYI I am still running into an issue where the UI shows the (non-default) router target in an uninitialized state while the router believes that it is displaying the default target. I still cannot figure out why.
I have RootRouter
> OrgRouter
> ... > DetailsDisplayRouter
> [LatestBillRunList SubscriberList]
and URL .../subscribers and I expect to see the SubscriberList
RAD report - which I do, but it is empty, even though the DB has the data, because the parent router believes it is displaying the other report. This only happens when I go to the URL in the browser, not when I click myself through the app to the state.
So how is it possible that DetailsDisplayRouter believes it is displaying LatestBillRunList while it should, and the UI does, show SubscriberList?!
The state of of the DB seems inconsistent when I compare the router and the corresponding UISM:
uism/asm-id DetailsDisplayRouter:
active-state :routed
active-timers {}
local-storage {:path-segment ["subscribers"], :pending-path-segment [], :target [::report/id :SubscriberList]}
dr/id DetailsDisplayRouter:
current-route LatestBillRunList
☝️ so the router and its UISM have completely different view of the world?!From the Tx log:
:40 SM(DetailsDisplayRouter) :timeout! :event-data {}
:40 SM(DetailsDisplayRouter) :timeout! :event-data {}
:40 SM(RootRouter) :timeout!
:38 SM(SubscriberList) :event/loaded
:38 SM(OrgRouter) :ready!
:38 dr/target-ready {:target [:org-nr "123"]} ; -> could this confuse DR to believe it shows the default view?!
:37 SM(DetailsDisplayRouter) :ready!
:37 LOAD subscribers
:36 dr/target-ready {:target [:com.fulcrologic.rad.report/id :SubscriberList]}
:34 SM(BEGIN): DetailsDisplayRouter {:path-segment ["subscribers"], :target [:com.fulcrologic.rad.report/id :SubscriberList]}
sorry, lost thread of discussion…did you look at wrap-rewrite-values
in RAD? It is an example of making a pluggable mw that can rewrite specific attributes as they are found.
The save format is just what form_state.cljc from Fulcro uses.
ok, open issue in Fulcro with what happens as best you can describe. Feel free to look through the Fulcro code. Look for uses of ido
and ilet
…those surround all Inspect reporting. I’m guessing the parallel txn_processing.cljc code is just missing a hook to report the end.
Sounds like a bug. The diffs calculate off of downloaded db revisions, and those are on demand now…must be a bug
right, sounds like a bug in either your code or RAD or DR. If the report doesn’t get a will-enter notification, it won’t start the UISM
hey @wilkerlucio can you transact a reverse link in datomic? i thought that was for querying only?
the RAD middleware is supposed to update fulcro's form delta, while still making it look like a form delta, then some code will translate it into a datomic transaction
(defmethod rewrite-value :order/id
[{user-id :user/id
firm-id :firm/id} [_ id] v]
(when (and user-id firm-id)
(if (tempid/tempid? id)
(assoc-in v [:entity/firm :after] [:firm/id firm-id])
v)))
that's a simple example
that method is defined in com.fulcrologic.rad.middleware.save-middleware
does that make sense?
I believe the report did start its UISM. You can see it did load its data. So all is OK - aside of the confused router
And there is even target-ready for the subscribers report. (it is followed by another one, for the ancestor router, no ide why. Perhaps that is messing it up?)
kind of, we tried changing the format, but getting this error now:
datomic.impl.Exceptions$IllegalArgumentExceptionInfo: :db.error/not-an-entity Unable to resolve entity: [:my.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}] in datom [[:my.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}] :my.entity/year 2020]
data: {:entity
[:my.entity/id
{:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}],
:datom
[[:my.entity/id
{:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}]
:my.entity/year
2020],
:db/error :db.error/not-an-entity}
java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: :db.error/not-an-entity Unable to resolve entity: [:my.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}] in datom [[:my.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}] :my.entity/year 2020]
this is what the form delta looks like:
{:com.fulcrologic.rad.form/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"},
:com.fulcrologic.rad.form/delta {[:my.domain.entity/id {:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}]
{:my.domain.entity/year {:before 2020, :after 2020},
:my.domain.entity/amount {:before nil, :after 1111M}},
[:account/id {:id #uuid "bd99f8e1-a679-4fe7-a82f-090838077bb8"}]
{:account/base-acres
{:before nil
:after [[:my.domain.entity/id
{:id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"}]]}}},
:com.fulcrologic.rad.form/master-pk :my.domain.entity/id}
@tony.kay I think would be interesting ot enable the new Discussions tab for Fulcro repository, what you think? did you got the notificaion?
you've got maps where i think you meant to place UUIDs
{:com.fulcrologic.rad.form/id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3",
:com.fulcrologic.rad.form/delta {[:my.domain.entity/id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"]
{:my.domain.entity/year {:before 2020, :after 2020},
:my.domain.entity/amount {:before nil, :after 1111M}},
[:account/id #uuid "bd99f8e1-a679-4fe7-a82f-090838077bb8"]
{:account/base-acres
{:before nil
:after [[:my.domain.entity/id #uuid "441dc0e4-f4db-456f-9876-a4c6cb4bd2e3"]]}}},
:com.fulcrologic.rad.form/master-pk :my.domain.entity/id}
^ perhaps that's the delta you wanted?
yeah, working now, thanks 🙂
I did not get a notification @wilkerlucio, but it if it persists and allows public interaction, it does sound like a good idea.
the history here is super annoying
yeah, I think you can go to the Settings of the repo and enable it
@tony.kay like this
Thanks for the tip..didn’t know they added that. Let’s see how it goes
should I open an issue...?
When using ::form/subforms
, how to make the subform items removable?
nah, open a PR if you find a fix. I don’t keep issues around I don’t have time to work on, in general
and I don’t
There are instructions for spining it up in dev mode in Development.md, and there are “LANDMARK” markers at the comm spots. I may look at it if I need it…but I never personally use that feature
so what do you do to check state changes over time, to find out which transaction changed a value in an unexpected way?
Perhaps it is just experience, or perhaps how I structure code, but I rarely find that useful.
Seeing what ran is always useful, but I generally know what things do, so diff is rarely useful
@wilkerlucio added that feature, and I'm sure it helps some, but not really me
so not high prio for me ATM, sorry
@tony.kay Put up a small PR that fixes a minor bug in fulcro-rad-demo
: https://github.com/fulcrologic/fulcro-rad-demo/pull/17. I wasn't sure what branching was appropriate; happy to make any changes that would make things more convenient for you. Thanks for all the work you've put into rad!
cool, thanks!