Fork me on GitHub
#fulcro
<
2019-04-05
>
lauritzsh20:04:15

Hey, I have been playing with Fulcro/Pathom most evenings this week when I had time and I feel I am getting close but there are areas I simply still don't understand. I have this very simple setup so far (code snippet) but I am really having trouble writing my UI queries. I can see with Fulcro Inspect the data is in the DB but how would I write the Root and TodoList query so I can see todos for 2019-04-01?

Andrew20:04:34

I'm really new to Fulcro as well so I'm not sure if this is the issue but your root query has ":todo-list/by-id" instead of ":todo-list/by-date" as I think you intended

facepalm 4
devo20:04:06

I think this is due to what you have in the store. Currently it seems like your store doesn't have any initial state, so that query cannot resolve to anything. The defined resolvers can find fields based on data present in the system, as none of them are global. So currently if you query for :todo/title, that can be resolved alongside any :todo/id entry in your state.

devo20:04:23

I believe you want a :todos/by-id entry in your store that has those todos organized by id, and a resolver that takes :todos/by-id as an input, and returns :todos/by-date as an output after reorganizing the by-id selection.

lauritzsh21:04:41

@andrew513 not sure how I missed that, I can even see that I tried that earlier but now I get {[:todo-list/by-date 2019-04-01] {:todo-list/by-date 2019-04-01, :todos [{:todo/id 1, :todo/title Mow the lawn, :todo/planned 2019-04-01} {:todo/id 2, :todo/title Wash dishes, :todo/planned 2019-04-01}]}} where before I just got {[:todo-list/by-date 2019-04-01] {}} so I wonder what I have changed since

devo21:04:48

Then you can have a top level query [{[:todo-list/by-date "2019-04-01"] (prim/get-query TodoList)}] that can join to your by-date entry and fetch a list of todos from that entry.

lauritzsh21:04:24

@U1RUG108P this is what my store (I assume Fulcro store) looks like

lauritzsh21:04:52

I don't understand the todo-list/by-date thing twice that I have

lauritzsh21:04:37

@U1RUG108P I'm not sure how that resolver todo/by-id -> todo/by-date would look like, wouldn't the input mean one specific todo or is that the entire map (basically a subset of my todo-database)?

devo21:04:41

the input is the value corresponding to the key specified as input. So an input of :todos/by-id gives you that entry in the map.

lauritzsh20:04:57

This for example gets the todos [{[:todo-list/by-date "2019-04-01"] [{:todos [:todo/title]}]}] (in Fulcro Inspect's Query)

tony.kay21:04:10

@mail228 @denis-v @andrew513 So I would not suggest you encode these kinds of things into you UI queries at all.

tony.kay21:04:32

You UI query model is about the general shape of the data, not the specific content.

tony.kay21:04:20

Your todo lists (with a pathom model, which is recommended) should be purely by ID, and should be encoded as :todolist/id. The book is a bit out of date …sorry, very busy.

tony.kay21:04:07

the idea of showing the items for some date perhaps has an encoding that is a bit different, depending on what you actually mean. What your encoding is more like a “global view of a filtered list of items”…I’d use a component like GlobalFilteredTodoItems (I’m being intentionally overly verbose for demo purposes), and that (IMO) would be some kind of singleton with a “current set of settings and content”

(defsc GFTodoItems [this props]
  {:query ...
   :ident (fn [] [:gfti :singleton])})
...

tony.kay21:04:07

The query would include the configurable attributes of this UI

tony.kay21:04:48

e.g. [:ui/start-date :ui/end-date :ui/pattern {:list/current-items (prim/get-query TodoItem)}]

tony.kay21:04:06

note that todo items would be normalized in their normal :item/id table

tony.kay21:04:01

thus a real UI for a given todo list in table :todolist/id would also point to some subset of the overall :item/id items.

tony.kay21:04:16

and this “filtered view of all todo items” is just a totally different animal

tony.kay21:04:46

Then you have options for populating this new beast: local mutations, full-stack loads, or a combo

tony.kay21:04:34

If all of your todo lists are pre-loaded, then a local mutation can look at the current settings of the GFTI component to see what to look for, scan the local table of :item/id, and fill in :list/current-items with the matching list of local item idents.

tony.kay21:04:44

If not, then you probably just implement a server query to load them like this:

(df/load this :server/filtered-todo-items TodoItem {:target [:gfti :singleton :list/current-items] :params {:matches pattern :start-date s :end-date e}})

tony.kay21:04:12

which would load all of those items, normalized them (updating ones that were already there), and targets the correct filterted list of idents into the correct component

tony.kay21:04:38

or some combo…maybe you load all items, target them, THEN do a post-mutation that does the local-only filtering

tony.kay21:04:06

Summary: It should be very very rare to ever use an ident with a specific ID in a component query

tony.kay21:04:55

idents in component queries are typically for looking up something at the root level at a pre-defined key (current locale, logged in user) such as :current/locale :en-US or :current-user [:user/id 32] where the respective queries might be [:current/locale '_] or {[:current-user '_] (prim/get-query User)]}

tony.kay21:04:11

note in both of those cases no specific db ID appears in the UI query

tony.kay21:04:32

the database uses idents to point to the things you need, or just has scalar values

lauritzsh21:04:50

Thanks, the help and your time is appreciated. I think I understand the gist of how to approach this with your GFTI example but I have really been struggling reading the book and applying the knowledge, not sure if because I'm unfamiliar with Clojure(Script) or the concepts are just really foreign to me. I also watched most of the videos (except UI/routing and the workflow ones). I'm determined to learn Fulcro because it seems like a good fit and provides nice abstractions but there's been a lot to take in with Fulcro and Pathom and it's not clicking for me yet

lauritzsh21:04:48

The use of queries, idents, initial state, mutations, resolvers, defsc, prim, df/load etc, it's just a lot of terms to learn and understand how to build with

tony.kay21:04:11

I totally understand your pain. New approaches are hard simply because they are foreign, even when they are simple 🙂

👍 4
tony.kay21:04:05

You’re dealing with a number of things at once: syntax, new language semantics, a new database format, etc.etc.

tony.kay21:04:19

go easy on yourself…anything new takes time to learn

tony.kay21:04:24

Like when you first learn to program with mutable variables…things like “a = a + 1” look totally insane (if you know algebra)

lauritzsh21:04:26

Yep, that's true, I wonder for that reasons if functional languages actually make more sense for new people than your typical OO language (Java or Python typically)

tony.kay21:04:48

I’ve seen studies to that effect, yes

lauritzsh21:04:49

It's almost midnight here so my brain is fried anyway but with a fresh brain tomorrow, I'll try and give the GFTI approach a go

lauritzsh21:04:35

Thank you 🙂