Fork me on GitHub

I think I missed the hack where you don’t have to restart your REPL when you make changes to the backend in Fulcro RAD. Can someone share? Thanks!


I have a tabular report that RAD is generating for me. I've been using ro/row-query-inclusion to include some data that I use to render a single chart depending on which row is selected. It's getting a bit heavy to include that query in every row, regardless of whether it gets selected or not. I'm refactoring to call a mutation in ro/on-select-row to merge just the selected row's chart data, but I feel like there's an easier way and I'm just overthinking it. There is an attribute with a resolver that returns the exact data I want, requiring just the pk/id. Any high level advice to do it more idiomatically, or is using a server mutation the solution I probably need?

Jakub Holý (HolyJak)20:11:36

I don't know. What you describe sounds pretty OK to me.


I think a load is what I’d use, on the click of the row, not as a query inclusion. Well, more precisely, I’d include :ui/chart-data in the row query inclusion. That won’t be sent to the server, so you won’t get data for it. Then on row click load your data and target it at the :ui/chart-data The row will have an ident (you get row props, so you can make it from that). If you’ve already got a resolver that can start from that ident and get to your chart data, you could load that with something like:

(df/load! this row-ident (rc/nc [:row/id :row/field])
  {:params {:target (conj row-ident :ui/chart-data)})
where :row/id is whatever kw corresponds to your row id, and :row/field is the key under which you’d normally ask Pathom for the chart data for that row.


These are just Fulcro components running a state machine…so, the normal Fulcro patterns still apply.


I'm having a bit of trouble getting this to work. Where ro/row-pk foo/id, I presume the row's ident is like [:foo/id 1]? When I try it like that, the target ends up with that same ident as its value, and the row-inclusion isn't found. I must be getting the ident wrong, but not sure how..?


and 1 is the ID of the row, and you ahve a pathom resolver that can go from that kind of ID to the desired chart results?


input :foo/id output :foo/chart-results


that kind of thing



ao/pc-input #{::id}
   ao/pc-output [::chart-results]


and that is installed and verified to be working (e.g. from the EQL tab you can send [{[:foo/id 1] [:foo/chart-results]}] and get the data?


If you run that load manually from the REPL you should see the chart results merge into the db


then it’s a matter of making sure targeting puts them under :ui/chart-results…oh…they are not normalized, but it still should work…but I’d verify the database looks right from a manual invocation


ro/on-select-row (fn [report-instance {::foo/keys [id] :as row-props}]
                      (tap> row-props)
                      (let [row-ident [::foo/id id]
                            target [::foo/id id :ui/chart-data]]
                       (df/load! report-instance
                                (rc/nc [::foo/id ::foo/chart-results])
                                {:params {:group-by :month}
                                 :target target})))}
Yes, the resolver works. It actually loads the results into [:foo/id 1 :chart-results]:
 {#uuid "ffffffff-ffff-ffff-ffff-000000000002"
   #uuid "ffffffff-ffff-ffff-ffff-000000000002",
   [{:period "2009-08-01", :count 4}
    {:period "2009-09-01", :count 4}]
    #uuid "ffffffff-ffff-ffff-ffff-000000000002"]},


Maybe it's this part? > When loading an entity (by ident), then this option will place additional idents at the target path(s) that point to that entity.


you loaded the ident…targeting won’t work on that…use a post-action 😛


it will auto-normalize and merge without targeting, it’ll just be at the “wrong key” for the UI to see it


so you just need to “move it” from the I/O key (::chart-results) to the one in the row’s query (:ui/chart-results)


we don’t want ::chart-results in the UI query becaue that would cause the initial report to load it


(I don’t have support for :without in the report state machine, or that would have actually done it)


so instead of target, use :post-action (fn [{:keys [state]}] (swap! state ...)


No worries 🙂 That makes sense. I hadn't thought of the approach of using a :ui/ key to avoid loading the data at all and the rc/nc function is something I had wanted but never came across in the docs. My plan was to use a query-only component this morning, until I read your tip.


So, load! is designed for this use-case. There is a param called :without #{::chart-results} that will elide the real thing from the query, and then you can use load-field! to populate just one thing…but RAD reports don’t give you access to that


thus this “workaround”


You could easily “derive” a new state machine definition that gave you access to the load params, and then you could just put the real thing in the query


I guess it would be a reasonable option to add to reports in general


Yes, a sort of deferred per-row field loading you could call it, I guess. Seems like expanding row data on click or some other action could be a common operation.


It is, that’s why core Fulcro has a mechanism for it 😄


just didn’t give a hook for it in RAD yet


RAD is sweet. Obviously I'm still building up my confidence with it and the lib is evolving but the shortcuts I do get out of it are very nice.


Thanks for your help as always!

👍 1

@U0CKQ19AQ so I saw you added and I'm trying to update my code to use it. It seems it's not as straight forward as I thought, because load-field requires a component instance and it doesn't look like there's an easy way to get at a generated row instance (BodyItem). I'm calling it like (df/load-field! report-instance ::chart-data) and it ends up doing the join on [::report/id ::MyReport], which understandably doesn't work correctly. Am I missing something?


Yes, you need to write a BodyItem of your own, so you can put your load field there


ro/BodyItem option


Got it, thank you 🙏