Fork me on GitHub
#om
<
2016-05-18
>
selfsame00:05:33

i guess you could add a key to the props and then use (om.next/set-query! this {:params (:foo props)) before it mounts

selfsame00:05:08

personally I would put an :account-view in the :ledger/data instead of a parent telling child how to configure

ag00:05:22

I reckon it鈥檚 not a data problem I can鈥檛 wrap my head around. Simple as it sounds: I need lists of similar data where it would group each list based on a property

jasonjckn00:05:38

is there a canonical way to call your parser recursively

jasonjckn00:05:57

right now i'm generating the 'env' myself in the recursive call

jasonjckn00:05:02

e.g. getting the children of the ast node

selfsame01:05:00

@jasonjckn: I think that's how you do it (but I've been out of the om loop for a few months)

jasonjckn03:05:06

i can't get query rerooting working

jasonjckn03:05:56

(defmethod remote-read :widget/two
  [{:keys [state query ast target] :as env} key _]
  (println "remote-read: " key query)
  (let [ast (update-in ast [:children 0 :query-root] (constantly true))]
    (pprint ast)
    {target ast}))
and
(defn send [{:keys [remote]} cb]
  (println "SEND: " (prn-str remote))
  (let [{:keys [query rewrite]} (om/process-roots remote)]
    (println "query: " (prn-str query))))
what's emitted from the send function is the unrerooted query, nothing changed

jasonjckn03:05:21

i looked at the AST and the :query-root is definitely being put in place

jasonjckn03:05:31

{:type :join,
 :dispatch-key :widget/two,
 :key :widget/two,
 :query [{:datomic/pull [:listing/title]}],
 :component om-admin-v2.core/ListingList,
 :children
 [{:type :join,
   :dispatch-key :datomic/pull,
   :key :datomic/pull,
   :query [:listing/title],
   :component om-admin-v2.core/Listing,
   :children
   [{:type :prop, :dispatch-key :listing/title, :key :listing/title}],
   :query-root true}]}

jasonjckn03:05:15

i also tried it on the outer join and that equally had no effect

jasonjckn03:05:57

s/unrerooted/root/

jasonjckn04:05:27

nevermind, I figured it out

jasonjckn04:05:36

hmh, now the rewrite function doesn't work ;-/

jasonjckn05:05:43

aside from the bug, om/process-roots is a neat function

jasonjckn05:05:03

especially when you have multiple query roots

tomjack17:05:56

jasonjckn: the ast is not unparsed 馃槥

tomjack17:05:52

(.. or you could just put the query-root in the :query, not the :children?)

tomjack17:05:07

and, warning re ast-zip there: if you zip/edit and touch children, you are of course 'on your own'

jasonjckn17:05:54

@tomjack: someone is going to fix the bug though right?

jasonjckn17:05:01

i have a workaround for now

jasonjckn17:05:14

i was using the "API" properly afaik

tomjack17:05:23

I don't think it's a bug

jasonjckn17:05:42

so

{target (assoc-in ast [:children 0 :query-root] true)})
is incorrect?

jasonjckn17:05:53

what's the right code

tomjack17:05:03

I could be wrong, but I think so, yeah

jasonjckn17:05:24

i can set :query root on the outer join and it propagates to the send function via meta data around the outer join

jasonjckn17:05:40

but when I set it on the inner join, it doesn't get passed to send function

jasonjckn17:05:00

om/process-roots is clearly meant to read :query-root true recursively on any joins in the query expression

tomjack17:05:13

any changes you make to :children are ignored, what matters is :query

tomjack17:05:48

fix-query above is designed to update :query to match :children (assuming this has already been done for the children)

tomjack17:05:38

you could just touch :query instead. if you know it's a join, I dunno... (update-in [:query 0] vary-meta assoc :query-root true) or something like that?

jasonjckn17:05:39

I see what you're saying

jasonjckn17:05:01

side note: can't I just call om/ast->query

jasonjckn17:05:05

instead of your fix-query

tomjack17:05:36

you could use (comp om/query->ast om/ast->query) maybe?

tomjack17:05:56

fix-query just does one step, doesn't walk the whole thing

tomjack17:05:53

or, yeah, you could take the :children ast's, touch them, om/ast->query them, then put that in your ast's :query?

jasonjckn17:05:35

i think he's an large om contributor and he's setting query-root on the AST

tomjack17:05:09

it works on the ast itself, just not the :children 馃槙

jasonjckn17:05:20

i'll try updating the :query now

tomjack17:05:37

the ast representation is redundant and om doesn't want to do unnecessary work here, I guess

tomjack17:05:31

eh, I dunno if it's about unnecessary work really. the representation is redundant so they've gotta pick one of :query or :children to pay attention to

tomjack17:05:15

(..and paying attention to :children would mean recursively converting the entire ast to queries, which is more work)

jasonjckn17:05:26

i would have preferred they never read :query-root in AST under any condition

jasonjckn17:05:28

too confusing to me

jasonjckn17:05:02

maybe even return query expression from remote read not ast

jasonjckn17:05:20

why would you reroot the root of the AST

jasonjckn17:05:38

thanks for the help btw

jasonjckn17:05:50

@tomjack: ok so :query works

tomjack17:05:38

sure, this confused me at first too

tomjack17:05:57

the place to look in the source is at om.next.impl.parser/ast->expr's extra boolean argument and its callsites

tomjack17:05:46

(side note: I do think there is a bug that query-root doesn't work for props, so.. hopefully you won't try that)

jasonjckn17:05:38

just need it for joins, but I hope there's an issue tracking that

jasonjckn17:05:30

i'm trying to choose a web framework for my teams v2 product, i can't for the life of me figure out if om.next is a good choice or not for our situation, I think the lack of documentation, maybe not quite bug free yet means it's not quite ready yet, I also don't know if i can truly understand the om.next source code at this point since i'm new to cljs/react/etc

jasonjckn17:05:57

so probably reagent is a safer choice , albeit the state code could become spagetti code over the life of the project

jasonjckn17:05:46

it's definitely a marvel of work though, huge respect

dnolen20:05:00

@jasonjckn: the learning curve is relatively steep and the documentation is lacking

dnolen20:05:20

but in reality the project probably needs 10X more documentation than it currently has

dnolen20:05:39

like 10X more documentation than there is code

jasonjckn20:05:50

yah, another possibility is that I own the parser backend part of the project, and I get my team up to speed on the defui stuff, which is relatively the same as just plain react no?

dnolen20:05:52

so that鈥檚 not going to happen anytime soon

jasonjckn20:05:00

that would simplify it for the team dramatically

dnolen20:05:13

reagent is easier to pick up, and it鈥檚 very popular, very well supported

dnolen20:05:39

and I suspect if you understand om.next you can model your Reagent project accordingly

jasonjckn20:05:17

Well what problems does om.next solve that reagent + global atom doesn't?

jasonjckn20:05:46

the query expression provides some element of decoupling between the ui data tree and the underlying source of the data

dnolen20:05:52

it has a much more disciplined notion of synchronization and data fetching

dnolen20:05:04

it forces you to separate network crapola from components

dnolen20:05:19

no stateful gunk in your components, no fetching logic, no event spaghetti

dnolen20:05:42

i.e. it makes doing it the wrong way extremely painful

jasonjckn20:05:57

i find myself writing parsers like if namespace of the keyword begins with "widget" then recursively descend into the children, these :widget/foo are just for the ui data tree purposes but they don't correspond to any actual data on the backend

jasonjckn20:05:19

so it's according to the syntax i'm using a join, but it's just boiler plate

dnolen20:05:39

I don鈥檛 know what you are doing or how your trying to do it but that鈥檚 the other thing

dnolen20:05:47

nobody cares if your queries are local or remote

dnolen20:05:51

it鈥檚 completely irrelevant to the components

dnolen20:05:19

and you can change your mind later since you didn鈥檛 write that logic into the components

jasonjckn20:05:38

yah, that's nice, maybe you change your mind that some state should persist across browser sessions

jasonjckn20:05:45

e.g. move it from datascript to datomic

dnolen20:05:55

lots of stuff like that

jasonjckn20:05:11

i really like the separation because it will enforce some discipline on a large codebase on how things are organized

dnolen20:05:13

so the whole thing is biased by all my experience doing front end stuff and needing to make changes all the time

dnolen20:05:19

and being pretty bored with refactoring

jasonjckn20:05:24

and we can just have 1 or 2 people specialize in parsers, but the whole team doesn't need to know

dnolen20:05:27

which I consider a complete waste of time

dnolen20:05:38

if I refactor I only want to touch code that matters

dnolen20:05:41

not fix messes

dnolen20:05:09

but all this is from lots of experience

dnolen20:05:20

if you haven鈥檛 been doing this for 10 years you might not get it

jplaza20:05:29

That鈥檚 why people end up re-writting apps all the time

jasonjckn20:05:28

dnolen: Q, the query expressions communicate 'joins' with { } but whether that's a join in the backend is completely dependent on that data store

jasonjckn20:05:44

so seems like a lot of work around converting query expressions to backend queries unless you are on datomic

jasonjckn20:05:52

i'm trying to understand the win here

dnolen20:05:59

@jasonjckn: there鈥檚 a lot of stuff to do even if you use datomic

dnolen20:05:06

validation, auth all that stuff doesn鈥檛 go away

dnolen20:05:44

but now if I want to add some new data to the frontend I don鈥檛 have to go mucking around so much with the backend

dnolen20:05:03

new field in the schema, change the component query, go on a coffee break

dnolen20:05:59

mobile client need lighter payload, done, etc.

jasonjckn20:05:49

nods thanks for passing along the experience

currentoor20:05:54

is it a bad idea to call om/transact! inside of a client mutation?

dnolen20:05:01

@currentoor: seems weird to me yes

jasonjckn20:05:39

is there a function for validating whether a piece of data conforms to a query expression spec

jasonjckn20:05:54

effectively like a schema validator

selfsame20:05:16

@jasonjckn: re choosing om.next - I feel like it should be paired with projects that take advantage of it.

anmonteiro20:05:38

@jasonjckn: not for validating that a piece of data conforms to query expressions specifically, but there is validator in factory, which is much more general and you can implement that on top of it

selfsame21:05:05

I'm using it for a library catalog kiosk at work and it's been wonderful - idiomatic normalized data and queries, no weird read methods.

jasonjckn21:05:35

open source?

selfsame21:05:05

But porting a personal project that doesn't have idiomatic top level data/components has been a big stumbling block.

jasonjckn21:05:07

no reference to validator?

selfsame21:05:37

oh sorry i was not reading the chat log

anmonteiro21:05:53

@jasonjckn: validator is just a function you pass to om/factory which takes props

jasonjckn21:05:23

so it's a way to plugin a schema library

anmonteiro21:05:45

e.g.:

(om/factory MyComponent {:validator (fn [props] (cond-> true (not (contains? props :foo)) not)})

anmonteiro21:05:10

must return truey / falsey value

anmonteiro21:05:18

we assert on its return val

anmonteiro21:05:04

@dnolen: just submitted this which completes the fix for #679 (joins deep in recursion; this time for union recursive queries) https://github.com/omcljs/om/pull/686

anmonteiro21:05:26

a use case that I鈥檇 forgotten when working on the first part

anmonteiro21:05:54

whoa that was quick

jasonjckn22:05:18

having to write (dom/br nil) is annoying compared to [:br], any solutions here besides rolling my own?

jasonjckn22:05:51

i started talking about the design decisions of om at our v2 meeting, and now everyone is all fired up about om.next lol

jasonjckn22:05:15

we'll see what happens after they actually work through the material, might get some blank stares