Fork me on GitHub
#fulcro
<
2019-02-02
>
tony.kay01:02:56

made sense at the time (3 yrs ago when we were figuring it out)

👌 5
hmaurer13:02:01

Good morning 🙂 On the topic of data-loading, I ran into the following issue: Consider the following component:

(defsc App [this props]
  {:query [:db/id :router/screen {:current-user [{:user/course (prim/get-query Course)}]}]}
  ...)
In order to load data for this component, I need to either be able to do something like this: (df/load app [:current-user :user/course] root/Course {:target ...}) (where [:current-user :user/course] would be a path, not an ident, which I know is not a valid use of df/load) Or something like this: (df/load app :app root/App {:target ...}), but I would need to filter out :db/id and :router/screen from the query before sending it over? A third option (which I am currently doing) is not having these two levels of query nesting in the App component, like this:
(defsc UserCourse [this props]
  {:query [{:user/course (prim/get-query Course)}]}
  ....)

(defsc App [this props]
  {:query [:db/id :router/screen {:current-user (prim/get-query UserCourse)}]}
  ...)
And then load this: (df/load app :current-user root/UserCourse {:target ...}) What approach should I take? Is there another option I am missing?

hmaurer13:02:02

I should mention that I wasn’t too happy with my current option (the third option) because it forces me to have a UserCourse component which is essentially just holding a query

wilkerlucio13:02:10

@hmaurer components just to have query are totally ok thing to do, but to me it seems like you are missing a "Course" entity, I would put an ident on UserCourse too, its part of your data path so makes sense to have a component for it

hmaurer13:02:14

@wilkerlucio thanks! so you would avoid my first scenario where I am querying two levels deep before passing data to a component? i.e. {:query [:db/id :router/screen {:current-user [{:user/course (prim/get-query Course)}]}]}

wilkerlucio13:02:44

thats often a bad idea (still have some valid cases, mostly at leaves, and things you canat normalize for some reason, but normalizing is better in most cases)

hmaurer13:02:15

Alright. The way I was struggling to load data for this query hinted that it was a bad idea but I wanted to make sure. Thanks 🙂

wilkerlucio13:02:28

no worries, specially at the "up most" parts of your query you will want to avoid direct nesting (multiple levels at same component query)

hmaurer13:02:01

Yep. It seems like this wouldn’t be as much of an issue for nested components, but at the “up most” part I ran into this data loading problem

hmaurer14:02:12

@wilkerlucio also, while I am at it, another question on routing: the doc (Fulcro’s) contains a few examples of routing. Pages are routed based on table names. Sometimes pages have a dummy id (i.e. 1) if there is only ever one page under that table, but sometimes they have an actual ID (e.g. if the page shows a user which has an id in the system). What about pages that have more than one parameter? e.g. a page that renders a query that has N parameters?

wilkerlucio14:02:37

you can you EQL parameters to send more data, the identification needs to stay from ident but you can send extra params https://github.com/edn-query-language/eql#parameters

hmaurer14:02:24

@wilkerlucio would you use a vector as the id then, if it is based on multiple parameters?

wilkerlucio14:02:21

are you talking about multiple routing params? one other option is making your ident value something more complex, the ident value can be anything (a vector, a map, a map of maps...)

wilkerlucio14:02:07

what I mean by main identification is that somtehing will have to point the correct query to run, that needs to be flat and one ident key for each possibility

wilkerlucio14:02:23

but the "right side" can be anything with complex data, makes sense?

hmaurer14:02:30

Yes I was, I should have been more precise

wilkerlucio14:02:35

in the end, complex ident value or params are just separated channels you have available, so you can use what makes more sense in your case

wilkerlucio14:02:56

but will take some trial and error to understand what works for each

wilkerlucio14:02:10

in general I prefer params over complex idents because they separate the "main info" from the extra details

pvillegas1214:02:19

@wilkerlucio taking a look at pathom at the moment. My backend right now is all done in datomic. As I can use the fulcro queries (EQL) to directly use Datomic pull syntax, what is a good way for this to interact with datomic? Would I only have one resolver that calls d/pull?

wilkerlucio14:02:59

@pvillegas12 hello, yup, doing pulls is what I hear most people are doing with datomic

pvillegas1214:02:32

Would I have a single resolver then?

wilkerlucio14:02:59

kind of one per entity

wilkerlucio14:02:21

I have never played directly with datomic from pathom but I'm starting to want to make a more direct usage of it, maybe we can figure some easy integration layer

pvillegas1214:02:21

If I have a look up ref, I can hit only one resolver, as I have a call directly to d/pull

pvillegas1214:02:47

I guess the resolver per entity makes sense when hitting lists of entities

pvillegas1214:02:04

at that point, with datomic, one has to use datalog to query for those entities

pvillegas1214:02:18

I have something like this for an integration entity, but this can work for all entities if you know where to start in the graph

(defquery-entity :integration/by-id
  (value [{:keys [conn query]} id params] 
             (d/pull (d/db conn) query id)))

timeyyy15:02:43

I'm trying use some js components in fulcro. However the rendering (css styles) of the components isn't working correctly. Forcing the children didn't have an effect. I would appreciate some help on this -> https://github.com/timeyyy/fuclro-aws-amplify

tony.kay18:02:19

I think you’re going to have to narrow you example down to a gist…expecting free support for someone to read and understand an entire repo is a bit much….at least some link to the line you’re working on

timeyyy18:02:06

Hey tony. Thanks for taking the time to reply. The repo is lein new fulcro with the getting started for aws-amplify react. Here you can see how i'm importing the react class and using it https://github.com/timeyyy/fuclro-aws-amplify/blob/master/src/main/amplifytest/client.cljs#L23. I would be open to paying money to pair over this problem, i'm not getting anywhere 😞

tony.kay18:02:36

shadow-cljs cannot pull in css files

tony.kay18:02:47

See the shadow-cljs user’s guide

tony.kay18:02:46

hmactually, I think it was on his blog…let me see

tony.kay18:02:20

You might ask on #shadow-cljs

tony.kay18:02:38

I’m guessing “it otherwise works”, but just doesn’t get all the CSS

timeyyy18:02:08

hmm, ok so i think i found the blog you were talking about

tony.kay18:02:32

😄 see above

timeyyy18:02:18

oh right yeah. Yeah as you said it seem to work besides the css. Thanks for your help

tony.kay18:02:53

The fragmented js ecosystem is a hassle at times

hmaurer15:02:02

When you trigger a load with df/load, how can any component in the subtree of the query check if their data is loading? As far as I can tell the load marker can only be added under one key, but that doesn’t allow any component in the subtree to check if their data is loading

hmaurer16:02:14

@wilkerlucio again, if you know about this 🙂

pvillegas1216:02:10

pass the load marker down through props

👌 5
pvillegas1216:02:36

or use a lookup such as ['_ marker]

hmaurer17:02:43

https://github.com/fulcro-legacy/fulcro-template/blob/develop/src/main/fulcro_template/ui/html5_routing.cljc#L93 Why is the follow-on read on :pages required here? I don’t understand Fulcro well enough to make sense of the comment, namely: > the :pages follow-on read, so the whole UI updates when page changes

hmaurer17:02:04

Why wouldn’t the whole UI update without it? And why does it update with it?

hmaurer17:02:11

Another silly question. I set up my router to target a resource, i.e. the URL /app/task-set/1 points the router’s target to [:task-set/by-id 1]. The issue is that at first the data isn’t loaded (data under that ident is nil), so the router can’t computer an ident for the component and it breaks. I was thinking of transacting :task-set/id 1 under that ident before routing to it. (a) is that the right approach? or should I use merge!? (b) if I use transact!, can I use a built-in mutation for this?

miridius20:02:25

hi all, is there a way I can fire some code (a mutation or whatever) after the render of a df/load completes? If I use a postmutation it fires too early

miridius20:02:55

I have some code which will update the visibility of my footer depending on how far down the document the user is scrolled, and it depends on knowing the current document height (because if that's smaller than the browser window then the footer should always show). My problem is that my initial data load adds a bunch of data to the DB, but it takes some fraction of a second before that is rendered to the UI and the document height updates. I'm currently solving this with js/timeout but that's clearly not ideal

tony.kay21:02:53

@miridius unfortunately Fulcro doesn’t really have solutions for some of these low-level React sequence things (Load completes, calls post mutation, and :refresh determines the components that get re-rendered)…but behavior “after render” is purely a React concern

tony.kay21:02:39

https://stackoverflow.com/questions/26556436/react-after-render-code (requestAnimationFrame looks like one of the better suggestions)

tony.kay21:02:13

(2nd answer)

hmaurer21:02:07

Hi @claudiu 🙂 @tony.kay is telling me that you have a project with HTML5 history. Would you mind sharing how you handle route change events? I was taking inspiration from https://github.com/fulcro-legacy/fulcro-template/blob/develop/src/main/fulcro_template/ui/html5_routing.cljc#L97 but apparently it might be a little outdated

claudiu07:02:10

Took a bit of break, just got back to working on it, currently I'm 30% into a new version and probably a alpha release. Working on changing the interface a bit & dropping some dependencies but the concepts and most of the code is the same.

claudiu07:02:05

If you find anything useful and have any questions, glad to help out.

hmaurer13:02:29

Thanks @claudiu, I’ll check this out 🙂