Fork me on GitHub
#fulcro
<
2021-10-25
>
Duck Nebuchadnezzar11:10:05

What is the right way to fetch a ref attribute for a report, but I also need some of the data joined to that ref for formatting. I've added a row-query-inclusion and it was pulling down the right data, but it doesn't appear in my props unless I remove the attribute. When I remove the attribute, the data shows up, but I no longer have the column to format.

Duck Nebuchadnezzar11:10:49

setting a the report/column-EQL field on the attribute to a bogus key seems to allow for those keys to not conflict, but that's obviously not the right solution.

Duck Nebuchadnezzar11:10:47

I think what I really want here is a map from qualified keys to functions in the report options that will take the matched column attribute and return a query to be used in place of the qualified key... or an explanation of why I'm on the wrong track.

tony.kay00:10:26

So, when you list columns in a report, that is what is used to generate the query...it's just a macro. The column-EQL on an attribute is typically what you want, and in that case you don't want row-query-inclusion, since those are added AFTER the columns are added, so you'll have dupes.

tony.kay00:10:50

Make SURE your column-EQL is a map, since it is a single element of EQL. The only two values that make sense are a single keyword (the default) or a join (which is a map joning on the keyword of the attribute).

tony.kay00:10:06

then you'll need a column formatter, since nothing will know how to render that column. Using a custom BodyItem (in which you hand-write the query and rendering of the row) is the completely general case, and ignores column-EQL and row-query-inclusion...those latter two options let the macro generate a row component for you, but if you specify one, then there is nothing to generate.

Duck Nebuchadnezzar00:10:08

is it normal then to have attributes used just for ui then. Because I don't think I would want to override my attribute to have the same query as is needed by a ui component. Also, I can't seem to get the joining to work like described in that link, If I add my currency name attribute to my account report, it's not following it through the account/currency ref, so I think I'm misunderstanding that (I assumed that didn't work)

Duck Nebuchadnezzar00:10:14

So I had a custom formatter, but I was trying to get the name pulled in, but if I specified the currency ref attribute, then I couldn't include that query (the name wasn't getting merged in)

Duck Nebuchadnezzar00:10:33

so if I had an attribute to hold that query, pathom wouldn't really need it for anything because that job is being served by the currency ref

tony.kay00:10:35

column-EQL is just used by reports. You are, of course, allowed to create attributes that are not tied to db schema, make resolvers for them, and use them in reports.

Duck Nebuchadnezzar00:10:16

ok, I think what I need to do is becoming clearer

tony.kay00:10:28

you're talking in "local code-speak" and have not shown me any code...so "currency ref" is gibberish

tony.kay00:10:46

So, I usually do the following: 1. Implement the resolvers 2. Use Inspect EQL tab to make sure I can get the data I expect from the back-end 3. Add things to a report Sometimes I do 1/3, then if it doesn't look right double-check 2. There's really not much to it...it's just making a standard defsc for you with a generated row component.

Duck Nebuchadnezzar00:10:38

That works out nicely. Thanks

cjmurphy12:10:40

I'm calling form/create! with options last arg:

(form/create! this BankAccountForm {:initial-state {:ui/context (comp/get-initial-state cqc/Context)}})
Should this work? It doesn't seem to and I can't see from the source code how it would. The doc string says of initial-state:
A tree of data to be deep-merged into the new instance of the form before form config
is added. This can be used to pre-set form fields to specific values.
That's exactly what I'm after but rad-routing/route-to! (which form/create! calls) just does things with history and calls dr/change-route! , where options (that contains the :ui/context key) are just route-params.

tony.kay00:10:53

That should work, assuming your value of initial state matches the real shape of BankAccountForm....NOTE: initial state for RAD forms is about FORM state, not COMPONENT state. You cannot initialize non-form data via that mechanism.

tony.kay00:10:20

:ui/context, I imagine is NOT declared as a form.

tony.kay00:10:12

If you want to hack in that kind of think you're going to have to work on a deeper level: E.g. customize the UISM fo/machine option, or try pre-merge (don't know if that will work in this case).

tony.kay00:10:44

The cleanest approach is to extend the form machine with your own customizations..it's pretty simple to do since UISM machines are just maps...just assoc-in new events and such.

cjmurphy03:10:05

Yes I was wanting :ui/context to be in COMPONENT state. In this case it is annoying that FORM state and COMPONENT state are separate. There's just one locally created bank account.

cjmurphy03:10:06

It is in fo/field-visible? of a ::bank-account attribute that I'm needing the context, so perhaps from this I can get to FORM state, where I'll find :ui/context has been put. I looked in DB Explorer and couldn't find :ui/context. And anyway all I have to look into from this is props, so that's not really a go-er.

cjmurphy06:10:53

A locally created bank account needs to know the country of the user. Without RAD it would just be a local mutation to create the bank-account, so I'd easily be able to see context (that has country). With RAD things get trickier. Maybe there's a mutation hook...

tony.kay14:10:22

you can add a link query to the query inclusion and get smething like user details from root level

cjmurphy11:10:11

That did the trick. Thanks 🙂

sheluchin14:10:23

In the summary section at the end of https://book.fulcrologic.com/#_taking_control_of_the_sub_dom_d3_etc, it mentions that: > We override componentWillReceiveProps and componentDidMount but the snippet does not make use of componentWillReceiveProps. Is this an error?

Björn Ebbinghaus14:10:57

Given that componentWillReceiveProps is deprecated, I say the docs just weren't updated. You should use shouldComponentUpdate in this case, since it is called every time the props change.

sheluchin15:10:16

Thanks for the clarification.

sheluchin15:10:17

Another question related to the D3 example.. I'm trying to incorporate this into the RAD demo repo where the UI is all CLJC. The D3 stuff is obviously JS, so I'm not totally clear on how to combine the two. Do I need to convert the UI to CLJS in this case since there are no server-side (CLJ) equivalents for the D3 stuff? I'm presuming that defining the D3 components using a CLJS conditional reader would not be sufficient, as it would still have to get incorporated into the CLJC root component. I've mostly kept to writing my UI in CLJS so far, so this is new territory for me.

sheluchin20:10:17

Thanks for the link, but I think that's a bit over my head at this level. I'm not clear how this text maps back to my question. Maybe this is a good sign I should take a break from trying to make things and go do the Advanced Minimalist Tutorial.

Jakub Holý (HolyJak)21:10:38

The idea is that for Clj write something that approximates the cljs thing. In the case of d3 - return empty svg / canvas?

Jakub Holý (HolyJak)21:10:59

BTW the UI does not need to be in Clj. If you don't plan to set up server side rendering then it's perfectly OK to rename the files to cljs. Don't make your life more difficult than it needs to be

bbss03:10:01

Right, use cljc if you need server side rendering and return a dummy element if you don't mind the pre-data-hydration looking off, else just use cljs. wrt using d3, you can call everything from cljs, just need to get used to the slight syntax differences in examples, I find that the d3 works quite well with cljs and react. Use react refs to pass to d3 where dom elements are required. In general useful functions to know about when interop with js libraries is to-array on your data if the library has trouble iterating cljs datastructures, and sometimes return types of accessor functions are expected to be JS objects (but usually they are primitives in the end, so you can actually use cljs in the accessors)

sheluchin15:10:20

Thanks guys.