# om

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

kendall.buchanan 00:36:33

I’m sure this is a common newbie question for Om (and I suppose Datomic), but what’s the value of {:person/name “Jane”} over {:name “Jane”}? Is it to help the code author keep track of context, or is it more meaningful than that?

kendall.buchanan 00:39:50

Reading Datomic Pull documentation, it appears to allow queries to cross relationship boundaries, but how does that relate to Om?

hueyp 00:40:52

with you define ‘root’ parse methods, but after that its up to you. one common method is to recursively call parse for relations

hueyp 00:41:06

but its not required at all

kendall.buchanan 00:42:00

Okay, that makes sense, and I suppose recursive parsing loses value when more than one object share the same keys?

hueyp 00:42:01

e.g. [{:user [:user/name {:user/friends [:user/name]}]}], will call the parser on ‘:user` but its up to you how you want to handle the query part

hueyp 00:42:55

I’m not sure of all the reasons behind namespaced keys, but in practice I’ve found them handy :simple_smile:

hueyp 00:43:04

just a bit of context~

kendall.buchanan 00:43:15

K, I’m essentially trying to separate out style (and culture) from what’s required (as I learn).

hueyp 00:44:23

the only area where I’ve found namespace useful apart from style is mutations … e.g. (todo/create {:text ~text}) … if you isntead do (todo-create {:text ~text}) you have to make sure you quote things so as to not namespace todo-create

hueyp 00:44:41

I’m not sure how to show a ` inside of a code block

kendall.buchanan 00:45:17

K, but that’s a case where you’re namespacing your query names, as opposed to raw data.

hueyp 00:45:37

the mutations yah, not the query props

hueyp 00:46:13

for query props not sure other than style, although as you mention if you recursively parse it is then very helpful as how to parse :person/name is always clear vs :name

hueyp 00:46:21

but recursive parsing is not a requirement

hueyp 00:46:25

its just one way to do things

kendall.buchanan 00:46:56

Thanks much, this has been super helpful. I thought for sure I was missing out on some deep detail.

taylor.sando 00:51:09

Namespaces are mostly to disambiguate similar attributes, and to model domain objects. Similar attributes can just be put into similar namespaces. For example, time/created might make sense for some domains, whereas, person/birthdate might be more accurate for a person.

kendall.buchanan 00:53:24

This is straight from the Om tutorial…

kendall.buchanan 00:53:26

'[:app/title (:animals/list {:start ?start :end ?end})]

kendall.buchanan 00:53:35

Better stated:

kendall.buchanan 00:53:43

(query [this] '[:app/title (:animals/list {:start ?start :end ?end})])

kendall.buchanan 00:53:55

Appears hear that the query is also cutting across object boundaries.

kendall.buchanan 00:54:15

In which case, the namespaces are essential, right?

hueyp 01:01:47

this might be ‘bad’, but I personally draw a distinction of some queries as ‘root’ and some as inner … like a query [:user/name :user/date-of-birth] … this could be a valid component query, but my parser doesn’t know how to handle it … those aren’t ‘root’ keys

hueyp 01:01:53

so your root keys need to be unique

hueyp 01:02:01

since that is what the parser dispatches on

hueyp 01:02:25

in this case [:app/title] is unique … but it could also be [{:app [:title]}]

hueyp 01:02:39

where :app is root, etc

hueyp 01:03:28

or [{:current-app [:app/title]}] or [{:selected-app [:app/title]}] etc

hueyp 01:04:13

this is probably not useful discussion tho :simple_smile:

kovasb 01:43:01

I'm having trouble merging path-optimized query results

kovasb 01:43:12

I'm querying on an ident to the remote

kovasb 01:43:23

stuff comes back, and somehow the state gets bonked

kovasb 01:43:40

is there a canonical :merge override?

kovasb 01:45:18

this is with alpha31

tomjack 01:58:27

@kendall.buchanan: om keeps a map from 'prop' keywords to the component classes querying for them in the indexer

kovasb 01:59:10

in general the merge functions have gone from 2 to 4 args since i checked last..

tomjack 01:59:34

if you don't have sufficiently unique prop names, I think too much could wind up there, which could maybe lead to some troubles -- e.g. I think 'follow-on reads' after mutations which use a not-unique-enough key will lead to unnecessary rerendering

tomjack 02:01:25

@kovasb: have you looked already at overriding just :merge-tree?

tomjack 02:01:56

@tomjack uploaded a file: Untitled

kovasb 02:02:56

yes ive instrumented all those things

kovasb 02:03:30

theres a number of calls happening an unfortunately its a little tricky to see which one is corrupting

kovasb 02:03:57

will instrument some more..

tomjack 02:04:18

I don't think there is a canonical merge override. so far I have only had to override merge-tree, which is called from the default merge (but maybe your situation is different)

tomjack 02:04:26

the default merge-tree is basically useless :simple_smile:

kovasb 02:06:51

have you gotten it to work with path optimized server reads?

tomjack 02:10:50

no, I don't even know what path optimized server reads are. but in any case the default merge-tree seems unlikely to work correctly

mping 11:37:37

is there any boilerplate for om-next with routing , compojure and db access?

anmonteiro 15:11:13

@mping: nothing like that, but you can probably start from this:

anmonteiro 15:11:41

it doesn't use compojure, but it wouldn't be too hard to use it instead

mping 16:51:19

@anmonteiro: and what about routing, any suggestion? I'm quite new to om

anmonteiro 17:09:30

@mping: I've written about routing in a blog post, hope you find it useful:

mping 17:46:01

thanks, I'll take a look. I've stumbled upon it before, but I'll read more carefully

curtosis 17:52:35

this is exactly the question I was going to start off my morning with. thanks! :simple_smile:

kendall.buchanan 23:01:13

Another noob question: What are the most common uses of data normalization in The tutorial uses a remote service returning two lists with duplicate records. Are there more common use cases?

kendall.buchanan 23:13:17

Bit more detailed example.

mahinshaw 23:24:12

@kendall.buchanan: Normalization is used to remove redundant data. It relates to normalization in a relational database. I don’t know of any reason’s why you wouldn’t want to normalize your data.

kendall.buchanan 23:25:14

I think I got it now – looks like the standard use case is to take a bunch of tables and combine them into more deeply nested graphs.