Fork me on GitHub
#om
<
2016-01-31
>
johnswanson00:01:37

has anyone else run into this? i’m just working through the remote sync tutorial simple_smile

artemyarulin05:01:40

Can anybody explain what the benefits of using datascript with om-next? I know om pretty well, but have no knowledge about datascript.

denik05:01:48

@artemyarulin: at this point I would not use it. You would have to write some custom logic for edge cases like link lookups (see om.next wiki "thinking-with-links")

denik05:01:31

@artemyarulin: you get datalog for queries and don’t rely on idents since datascript has a schema

artemyarulin05:01:50

@denik: Thanks. But pretty much if I stick with standard om-next queries for now then if I decide to move to datascript I would have to change all the queries across all the application?

artemyarulin06:01:05

They are completely different?

denik06:01:41

yes you would but while the syntax is, the query logic is not that different

denik06:01:03

in either case you end up doing id or top-level lookups

denik06:01:32

i pulled out datascript recently because I ran into issues and it only took an hour for 40 queries or so

denik06:01:22

if you don’t use datomic and don’t have a really very complex front-end, you may not need datascript at all

artemyarulin06:01:16

I would have a complex frontend indeed, that’s why I’m thinking about datascript. Why did you choose to start with datascript at first? What is the main benefit for you?

artemyarulin06:01:24

comparing to standard om-next queries?

denik06:01:38

I’m using datomic on the backend so I can resuse queries in cljc

artemyarulin06:01:51

oh, yeah, it makes sense then

denik06:01:54

I can’t think of much that datascript gives you that om.next doesn't

denik06:01:33

oh well db functions simple_smile

denik06:01:45

not sure you need those on the front-end though

denik06:01:25

functions you store in the database that can run other queries or transformations

artemyarulin06:01:46

ala stored procedures in big db, hm

artemyarulin06:01:37

Another reason for datascript is that I’m actually gonna write apps for mobile and DataScript could be a cross platform DB to use for both iOS and Android

artemyarulin06:01:06

Thanks in any case, I guess the right thing would be to setup and play with it for a while

denik06:01:50

yep, I think if you write react native through om it will provide just that. @artemyarulin ur welcome

hueyp08:01:51

if you don’t have links, your data is just a tree, do you still need idents?

anmonteiro10:01:34

@hueyp: links are not the only thing that make your data a graph

anmonteiro10:01:37

Links and idents are not related in that sense

anmonteiro10:01:00

I suggest you go over the components, identity and normalization turorial to understand what idents are for

hueyp10:01:48

I removed the Ident from Item component in https://github.com/omcljs/om/wiki/Thinking-With-Links%21 and it stopped working which confuses me

hueyp10:01:21

I’ll have to think about ident / links not being the same, I think I do confuse that

hueyp10:01:29

they seem same to me 😜

anmonteiro10:01:17

@hueyp: it stopped working because Om doesnt know how to normalize the data anymore

hueyp10:01:05

why does the item list need to be normalized? is it not okay for something to be a vector of maps? the vector entries have to be links?

hueyp10:01:20

like if item had no identity

hueyp10:01:21

for instance if something was a component vs entity … a person has a list of addresses, but there is no identity to address, it is just a component of person

anmonteiro10:01:32

@hueyp: normalization prevents data duplication, and complex update logic that results from it.

anmonteiro10:01:07

You can always not normalize data

anmonteiro10:01:42

But then you should not be calling db->tree

hueyp10:01:52

I need to look more at db->tree for sure. I can nest maps, e.g. if a person has a single address, db->tree works fine, but as soon as I make it a collection db->tree is unhappy

hueyp10:01:50

maybe that is not a supported structure of the ‘default’ db format

anmonteiro10:01:01

I'm pretty sure it's supported, if it's not returning anything you might 1. Not have the right idents in place; 2. Not have the correct queries

anmonteiro10:01:25

If you think it's a bug, make a minimal case and post it in this channel

hueyp10:01:58

but if the data structure is {:phone-numbers [{:area 123 :rest 1234567}]} … I don’t think an ident is appropriate?

hueyp10:01:11

like that phone number has no identity

hueyp10:01:42

but I still want to query {:phone-numbers [:area]}

hueyp10:01:10

thanks simple_smile I will definitely explore more, db->tree seems key 😜

anmonteiro10:01:22

@hueyp: right but querying has nothing to do with normalization

anmonteiro10:01:27

You can still query denormalized data

anmonteiro10:01:52

It's up to you to implement the parser logic anyways

hueyp10:01:44

yah, but I was hoping to avoid that by keeping things in the default db format and being able to use db->tree

hueyp10:01:00

db->tree seems awesome in that you define your roots and then it does the rest simple_smile

cjmurphy10:01:03

I thought the default db format was normalized. Things work better normalized. You only need db->tree if your data is normalized.

hueyp10:01:32

I don’t understand how {:phone-numbers [{:area 123 :rest 1234567}]} is not considered normalized

cjmurphy10:01:44

You can start with initial data that is not normalized and let on next normalize it for you.

cjmurphy10:01:13

Normalized data is full of idents.

cjmurphy10:01:29

:app/selected-button [:button/by-id 3] is normalized.

cjmurphy10:01:06

The Kanban demo really helped me.

hueyp10:01:25

would {:app {:selected-button [:button/by-id 3] :favorite-button [:button/by-id 3]}} also be normalized?

hueyp10:01:59

or does :app need to have a value that is an ident? only idents are allowed?

cjmurphy10:01:52

Is that state or query?

hueyp10:01:29

state, but terrible … I just want to make a structure which has nested maps

cjmurphy10:01:56

Fully normalized doesn't have many curly braces 😉

cjmurphy10:01:33

Yes. Notice the lanes comes in at the root query?

cjmurphy10:01:21

That seems to be required for tree->db to do its job, which is what happens by default when you don't give the reconciler an atom.

cjmurphy10:01:02

Here is Jannis's code simplified, so no rendering, just for the purpose of getting normalized data, which takes some time and you need to know how it works:

cjmurphy10:01:06

Good luck. simple_smile

raphael12:01:11

Hello, I don't undertand what is a om.next/factory? when I need to use it? in which case I need to use validator? Is there documentation on it?

raphael12:01:24

thank a lot simple_smile

cjmurphy12:01:01

It allows you to create an instance of the React component you defined with defui macro. Before you use it to create a React component ON can still call the static methods of the defui component.

krcz15:01:08

Hi, has any of you tried server rendering with Om Next? I want to have query-based components and use read-only app state on server to render them. Unfortunately I cannot see any way of running om next queries via parser other than using add-root!, which doesn't make sense with server rendering.

raphael16:01:28

why can't you use your parser? (my-parser {:state app-state} [:x :y :z])

raphael16:01:58

(maybe I didn't understand the question)

krcz16:01:22

As far as I understand in normal rendering logics, query results are added to the props, available in render function. I would like to have it done, so no special cases are needed.

jimmy17:01:49

hmm guys, does any one get this error on latest om.next ?

Uncaught #error {:message "No queries exist for component path (my-project.components.app/App my-project.landing.page/Page)", :data {:type :om.next/no-queries}}
I'm pretty sure I have static om/IQuery on both components, maybe I misunderstand anything ?

sander17:01:29

@nxqd does App’s query include Page’s query?

jimmy17:01:33

I will a bit investigation on this, normally it does.

iwankaramazow18:01:04

@krcz: for server side rendering take a look at https://github.com/arohner/foam maybe you could build on this...

hueyp20:01:47

with the thinking in links tutorial, if you move [:viewer _] down to SomeList it doesn’t work … is the idea you can only embed links in sub-queries, they aren’t proper ‘roots’?

hueyp20:01:48

e.g. [{:items [[:viewer _]]}] is legit, but [[:viewer _]] is not

iwankaramazow20:01:33

@hueyp: [:viewer {:items [[:viewer _ ]]}] is valid

hueyp20:01:19

in that query, the [:viewer _] does not require a parse method, but the :viewer does

hueyp20:01:38

that is at least my finding so far

iwankaramazow20:01:52

yes that's true, the reason for that is only top-level keys trigger reads from the parser

hueyp20:01:54

and sorry, the tutorial is :current-user, I switched it in my brain (too much relay)

iwankaramazow20:01:39

:viever and :item are the top-level keys here

hueyp20:01:43

so there is definitely the concept of top level keys, which is what I am slowing getting to 😜

iwankaramazow20:01:56

this page has some nice examples

iwankaramazow20:01:30

For example [{:a {:b {:c [:x :y]}}}] (from that tutorial), only :a will trigger a read

hueyp20:01:27

is there a convention on defining a top level key for ident lookups? e.g. I have an ident :item/by-id … I want to use it as a root … what is idiomatic? simple_smile

hueyp20:01:36

e.g. [:item/by-id 2]

hueyp20:01:23

I’m thinking make it a parameterized read, [(:item {:id 2}), but wondering if that is the way to go

iwankaramazow20:01:58

that's perfectly possible

hueyp20:01:25

or I guess thinking about it … you assign a root and just update its ident … [:active/item]

iwankaramazow20:01:14

that's how it'll probably work out

iwankaramazow20:01:27

you have a list of items normalized in :items/by-id Then you'll probably have some query like [{:items/list [:nr :name :description]} :items/active]

iwankaramazow20:01:02

two top level keys here: :items/list and :items/active

hueyp20:01:50

update: so you can do [{[:item/by-id 2] [:name :description]}] … the read method matches key :item/by-id and then the ident is in the env at :query-root, so [:item/by-id 2], and the query is in the ast at :query, so [:name :description]

hueyp20:01:12

I have zero idea if this always applicable, but works for a single case so far 😜

hueyp20:01:25

(defmethod read :person/by-id
  [{:keys [query-root ast state] :as env} _ _]
  (pprint (dissoc env :parser))
  (let [st @state
        query (:query ast)]
    {:value (om/db->tree query (get-in st query-root) st)}))

hueyp20:01:16

anyways, if I do need to query by id, this is way nicer than using a param

hueyp21:01:27

I feel like the key to learn om.next so far is re-reading things a bunch of times

hueyp21:01:38

because it always makes more sense the next time

iwankaramazow21:01:47

oh yea definitely

iwankaramazow21:01:54

the tutorial also helps a lot

iwankaramazow21:01:04

the one from tony.kay I mentioned

iwankaramazow21:01:33

if your read works in the example above, roll with it.

hueyp21:01:57

https://github.com/omcljs/om/blob/master/src/main/om/next/impl/parser.cljc — like this lists the AST … so I’m guessing your read methods can get QueryExpr := (EdnKeyword | IdentExpr | ParamExpr | JoinExpr) and then it goes on to list the ast stuff 😜

iwankaramazow21:01:33

In your read function above you can plug the full-query in om/db->tree Example: (om/db->tree '[{[:items/by-id 2] [:name :description]}] @state @state)

hueyp21:01:22

simple_smile (om/db->tree [{query-root query}] st st)

hueyp21:01:21

or (om/db->tree [(om/ast->query ast)] st st)

hueyp21:01:37

do you know of any kind of hook-in points for db->tree? like if I want to make a generated field, but not a root

iwankaramazow21:01:54

what do you mean by generated field?

iwankaramazow21:01:08

(Have to go, will probably answer tomorrow)

hueyp21:01:01

good question, initial thought is something goofy like :user/full-name but that can just be a function a component calls (e.g. query [:user/first-name :user/last-name], call full-name func). need to think about it more … might not be a real need simple_smile

hueyp21:01:07

and thanks for your help simple_smile

krcz21:01:25

@iwankaramazow it looks nice, but doesn't seem to support Om Next. And I don't need clj rendering, I'm experimenting with cljs backend, running ReactServerDOM render to text would be enough, I just need a way to fill in components with some provided parser, without mounting it to real DOM.

hueyp21:01:39

@krcz maybe the root-render config of reconciler?

hueyp21:01:18

a quick glance looks like add-root! might not care what target is, just passes it to root-render

krcz22:01:07

@hueyp that seems to be a good direction, thanks! add-root! even seems to support nil targets, maybe when I figure how it behaves in such case, it could be a solution.

pithyless23:01:11

I’ve been reading up on Om.Next (BTW, for an alpha-release library, the community has really produced a lot of documentation and videos!). One thing I am not convinced about:

transact! component `[(todo/add {:title “Get Milk”}) :todos/list :todos/counts …]
The need for every component transact! to be aware of all root elements that may be affected by a mutation. I understand the performance reasons for it, but can someone comment on how well it works in practice? Is there a lot of head-scratching when something is not re-rendering as it should? Sounds like a source of irritating bugs.

pithyless23:01:18

I wonder if it can be automated somewhat, e.g. if you’re using datascript and you just default to passing in all keywords from the static query.

hueyp23:01:31

I’m new to om.next, but its also a pain point in Relay — I think its just a hard problem simple_smile