# om

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

jeremyraines 23:05:35

I’m trying to understand what you’re doing in your send function. Specifically with om/process-roots. When I give that either my edn payload (what’s going to the server) or the response back from the server, it blows up

jeremyraines 23:13:50

was misreading the printed out :rewrite function as an error

jeremyraines 23:14:06

but, now that I’ve got that, these are the same:

jeremyraines 23:14:48

_ (println "rewrite") _ (println ((:rewrite (om/process-roots edn)) resp)) _ (println "resp") _ (println resp)

anmonteiro 00:25:48

@dnolen: I think I've found an edge case in db->tree ``` (db->tree '[[:my-route _]] {:my-route :something} {:my-route :something}) => {:my-route :something}


(db->tree '[[:my-route _]] {:my-route '[:something :else]} {:my-route '[:something :else]}) => {:my-route nil} ```

anmonteiro 00:26:42

db->tree will try to resolve the ident in the latter case, but I don't really want it to?

anmonteiro 00:26:54

because that might not even be an ident

dnolen 00:28:33

@anmonteiro: right this is known problem

dnolen 00:28:46

since there isn’t a ident type that we use

dnolen 00:30:10

oh hrm, yeah open a issue - should think about that

dnolen 00:30:16

maybe there is a simple heuristic we can use here

anmonteiro 00:30:44

will do, but one doesn't occur to me right away

anmonteiro 00:32:08

@dnolen: suggestion for the issue title appreciated

dnolen 00:33:06

maybe something like "db->tree naively resolves idents"

anmonteiro 00:33:28

this case is not ident resolution, I think

anmonteiro 00:33:35

or is it?

dnolen 00:34:08

I think we have some logic for resolving a ident and if get another thing that looks like an ident we resolve again

dnolen 00:34:47

rather what I mean is a query “link” resolves to an ident

dnolen 00:34:53

and that gets looked up

dnolen 00:35:06

maybe it’s misfeature? But it seemed convenient at the time

anmonteiro 00:35:19

yep you're right

anmonteiro 00:35:29

I'll look into it a bit

anmonteiro 00:37:11

@dnolen: right so I was looking in the wrong place

anmonteiro 00:37:18

there's even a comment stating what it does

anmonteiro 00:37:26

;; support taking ident for data param

jeremyraines 01:25:29

I’m still struggling to understand how to handle the response from the server after a server-side mutation. I now understand what the pieces of the response are, and how to find the :result piece which has the updated state I want to merge, but the means of detecting and grabbing it that I’m using (see if the vec’d response’s first entry’s second entry is a map with a :result key) seems really smelly. But it seems like that’s what this commit by @anmonteiro does, on david’s om-next-demo repo. (That, and removing datomic keys). I just want to make sure that’s just how it is and there’s not some transformation fn or other technique that people use for this that I don’t know about

tawus 05:54:40

If I have a query [(:list-with-args {:arg ?arg})] in a component and there is any mutation for this component, should I expect a read to be called for :list-with-args ?

currentoor 07:16:04

How do I make my project depend on the most recent version of

tawus 07:26:07

most recent version or snapshot ?

tawus 07:30:49

Are you using lein ?

currentoor 07:31:04

nope, boot but it’s probably similar

cjmurphy 07:32:28

Clone the repo then install to .m2. With lein this would be lein install. (sorry busting in!)

tawus 07:32:37

[org.omcljs/om "1.0.0-alpha30"]

tawus 07:32:46

for recent version.

cjmurphy 07:32:59

[org.omcljs/om "1.0.0-alpha31-SNAPSHOT"]

tawus 07:33:11

and for snapshot what @cjmurphy said :simple_smile:

currentoor 07:33:23

i see, and what does [org.omcljs/om "RELEASE”] do?

cjmurphy 07:33:27


currentoor 07:35:40

ok so there are four ways to do this lol, [org.omcljs/om "1.0.0-alpha30”], [org.omcljs/om "1.0.0-alpha31-SNAPSHOT”], [org.omcljs/om "RELEASE”], and what @cjmurphy said.

The first is the most recent version, the second is the latest snapshot (what’s a snapshot?), the third and fourth are the same as the latest snapshot?

currentoor 07:35:47

is that correct?

cjmurphy 07:38:04

I don't know what the RELEASE is. But SNAPSHOT and what I said are the same thing.

cjmurphy 07:38:43

And the alpha30 is like the current last release that DN chose.

cjmurphy 07:39:23

alpha30 will be more stable.

currentoor 07:39:57

@cjmurphy: ah i see, thanks

cjmurphy 07:40:13

I only just saw your lol :simple_smile:

currentoor 07:40:39

and the best way to find the latest release is in the project.clj file in the om repo?

cjmurphy 07:41:02

Yes, that's how I found it.

currentoor 07:41:09

cool, thanks

cjmurphy 07:42:46

With boot at least you won't have to remember to lein clean, lein deps projects that refer to om after you install it - well that's the theory with boot I think.

currentoor 07:43:05

so i’ve heard

cjmurphy 07:43:11

good luck!

currentoor 07:43:15

hopefully that’s true

george.w.singer 08:04:13

Should I have any problems running a server-side om-next remote parser with a clojurescript back-end targetting node.js/express.js? All of the tutorials I've seen so far are using pure Clojure on the back end. I still haven't wrapped my mind yet around how this part of the Om Next puzzle works.

artemyarulin 09:58:09

@george.w.singer: Haven’t seen anything like that, but using CLJS in Node is not a problem, so it should work

george.w.singer 12:48:03

@artemyarulin: sounds good. Are there any libraries I have to explicitly import into nodejs/express (via cljs) on the backend? Or is it all manual?

artemyarulin 12:53:18

@george.w.singer: Hmm, not sure. Maybe you can get some info here and referenced Foram therem. It’s about different thing, but could be a place to start

jlongster 16:47:52

@george.w.singer: I use ClojureScript on the server with express and it should work fine with no changes, just import om normally

thomasdeutsch 16:49:07

for performance reasons, i would like to store some data that is calculated during the rendering phase. so, when the next rendering occures, the render-fn will look if there is some cached data before doing the calculations again. I was thinking about using a second state atom that will only host the cache-data (without any connection to the app-state). Is this a bad idea?

danielstockton 16:53:23

not sure i understand, don't see why you couldn't have a separate cache that is a function from state -> cached value

danielstockton 16:53:32

seems orthogonal to anything om

thomasdeutsch 16:54:25

if the cache is a part of the state, i would have a rerender if the cache is updated. or can i prevent any rerender on a transaction?

danielstockton 16:54:45

why would the cache be a part of the state?

thomasdeutsch 16:54:45

(or ... prevent reads)

danielstockton 16:55:52

i think that om's involvement stops once it passes the correct props to your render function

danielstockton 16:55:57

what you do in render is your own business

thomasdeutsch 16:56:57

Ok... yes. I was thinking the same.

jlongster 17:04:37

How is managed? I see that it's added to in set-query!, and removed from in componentWillUnmount, but isn't there somewhere else that adds to it?

anmonteiro 17:05:26

@jlongster: are you asking that because you're seeing a nil value for that entry?

jlongster 17:06:37

no, I don't see any problems but I noticed that my parser function was being run at a weird time and I realized that componentWillUnmount modifies the state. I'm dynamically displaying various children that have queries, so when they are unmounting it updates that key, but I'm worried that new children aren't updating it

jlongster 17:06:41

so I may hit a bug later

jlongster 17:07:56

I'm using a virtualization library that only displays a subset of a large list in the DOM, and each of those rows has a query. It seems to work pretty well, but just wanted to make sure

anmonteiro 17:08:28

@jlongster: queries are only stored in the state if you explicitly set them for a mounted component

jlongster 17:08:30

example code if it helps that renders the VirtualScroll element:

jlongster 17:09:32

@anmonteiro: ah ok. will the swap! in componentWillUnmount always trigger the watch (which schedules a rerender) even if it didn't change the data?

anmonteiro 17:10:19

@jlongster: I don't know, but that's something I can try in a second

anmonteiro 17:10:34

it will however trigger the watch in the first unmount

jlongster 17:11:06

"first unmount"?

jlongster 17:11:30

I'm trying to avoid unnecessary rerenders

anmonteiro 17:11:46

when the key is not even there

anmonteiro 17:11:58

(swap! (atom {:a 1}) update-in [:b] dissoc 3) => {:a 1, :b nil}

jlongster 17:12:14

oh, weird

anmonteiro 17:12:24

it's how update-in works

jlongster 17:12:53

the keys of are component instances, correct?

jlongster 17:13:16

it will always be the "first unmount" then :simple_smile:

anmonteiro 17:13:19

if you didn't set the query for an instance there will be no entry under ::queries

jlongster 17:13:45

can we first check to see if this# is in before dissoc-ing it?

jlongster 17:13:49

that would solve it

anmonteiro 17:14:33

it probably would

jlongster 17:14:59

ok I'll make a PR

anmonteiro 17:32:24

@jlongster: looks good, does it solve your problem locally?

jlongster 17:32:32

yep! all smooth now!

grzm 17:38:27

anyone have or know of an auth/session example using om next?

danielstockton 17:43:20

gzrm, have you got a particular problem?

danielstockton 17:43:42

i hope to tackle auth quite soon

grzm 17:45:32

I'm just too new. Tackling a lot of new things at once. I'm trying to determine if I should use a separate remote for login, or maybe even just a normal POST to a login resource, or if I should try to handle it with a mutate like [(login/submit creds)]

danielstockton 17:48:10

I would handle it through a remote mutate, which returns the user on success and merges it into your app state. Then you can check for this user in your app-state to determine if you're logged in/out.

nha 17:49:46

Is it normal if
doesn't allow adding new TODOs ?

grzm 17:49:48

That's the way I'm working through right now. Actually, it's server-side stuff I'm struggling with (bidi/friend/carmine), not om-specific

grzm 17:49:59

@nha: it's a non-working example

grzm 17:50:23

@nha: I tried for quite a while to get it to work before someone told me the same thing :simple_smile:

nha 17:50:42

Well, thanks for saving me some time ^^

grzm 17:51:05

Think dnolen would accept a pull request adding such an annotation to the readme?

grzm 18:04:15

@dnolen: I've submitted a pull request to update the README for om-next-demo to note that not all the features work. I know this would have helped this newbie (me) quite a bit of time and I've seen others ask similar questions regarding the om-next-demo:

rauh 18:14:48

@grzm: Def. use a separate url/remote for login stuff, at the very least you want to limit the requests per IP with something like nginx. Or of course you can do that within the server if you have the time to implement such logic.

dnolen 18:17:38

@grzm: OK, but not a priority for me

grzm 18:18:02

@dnolen: understood.

artemyarulin 19:08:24

Most of the articles and wiki examples mentioned that you can (or probably would) edit the AST for remote fetch. Is it OK to change :params as well?

dnolen 19:08:59

anything about the AST is OK as long as you’re fine with the consequences

dnolen 19:09:21

as in we don’t really care what people do - it’s meant to be flexible for a reason

artemyarulin 19:12:35

@dnolen: Got it. BTW - just wanted to say thank you for om-next: learning curve is a bit of a problem, it’s not easy, but once I got it - it’s indeed very simple and powerful at the same time

dnolen 19:12:52

@artemyarulin: glad to hear it!

jlongster 19:44:57

@tony.kay: I'm starting to see the benefits of transacting to perform remote fetches. it would solve a problem I have right now. did you mention that you talk about it in your tutorials? I don't see anything like it in there

jlongster 19:48:18

I want to blow away the result of a previous remote fetch so that my component knows that it's loading again. right now I just check if the data exists at all, and if not I assume it's loading. but I can't blow away the current data by just changing query params.

tony.kay 19:53:02

So, no it is not in the tutorials...the tutorials are Om. The extensions I'm talking about are part of the stuff I'm trying to get open-sourced with my company....having lunch with the CTO may be able to share very soon :simple_smile:

tony.kay 19:53:11

@jlongster: ^^^

tony.kay 19:53:28

Framework stacked on Om Next

jlongster 19:53:53

well, I see how it would work so I'll probably just implement a simple version for now

artemyarulin 20:29:08

hm, what the purpose of :query-root in context of read parser and remote calls?

jlongster 20:43:57

@artemyarulin: it marks the ast so you can use process-roots in your send function, which transforms the query to make all the query roots top-level and sends off those to the server instead of the raw UI query

artemyarulin 20:45:51

hm, any examples of this? I’m having a problem that send function receives really a big query, while real data it cares about far deep down. I guess process-roots solves exactly this issue?

artemyarulin 20:46:03

@jlongster: ^

jlongster 20:47:57

assuming you've marked certain parts of the ast with query-root

artemyarulin 20:48:13

something like that?
{:remote (assoc ast :params (find data :path) :query-root true)}

tony.kay 20:50:07

@anmonteiro: See a regression in the indexer when flowing through the code you changed for dyn queries. Cannot read property 'call' of null from the last line shown in the snippet below. Thoughts?

tony.kay 20:50:13

@tony.kay uploaded a file: Untitled

jlongster 20:50:26

@artemyarulin: did you mean assoc-in?

artemyarulin 20:51:20

@jlongster: Well, I didn’t, but I’ll try :simple_smile:

artemyarulin 20:52:02

well, actually from tests in om-next:
(defmethod precise-read :real/key [{:keys [ast] :as env} _ _] {:remote (assoc ast :query-root true)})

jlongster 20:52:46

@artemyarulin: right, you just mark any point with :query-root, usually you are recursively calling the parser and look for specific keys and then you can do that simple assoc

tony.kay 20:52:52

@anmonteiro: Hm...maybe not....strange. Let me look more

artemyarulin 20:53:49

@jlongster: Yep, this is exactly what I’m doing: (defn read [{:keys [query data state target parser ast] :as env} key params] (case key :current {(or target :value) (assoc ast :params (parser (assoc env :data (get-in @state (get @state key))) query target))} :content (if-let [c (get data key)] {:value c} {:remote (assoc ast :params (find data :path) :query-root true)})))

jlongster 20:55:04

oh, I misread your code before, I think that works yes

artemyarulin 20:56:12

thank you for your help!

jannis 21:04:06

Does query not support joins on link properties? E.g. (query [_] [{[:current-user _] [{:profile (om/get-query UserProfile)}]}])

hueyp 21:11:08

I ran into some indexer bugs with that but I think @anmonteiro fixed them on master

tony.kay 21:23:38

@anmonteiro: Actually, it does seem to be a regression when using links ([:x '_] in joins). My app begins working again if I change the line mentioned above to:

(if (or (nil? loc) (empty? path)) (line 108 of commit 8f31b)

tony.kay 21:24:08

That is probably not the correct patch...I'll see if I can write a test that demonstrates the problem. It shows up when indexing on add-root

stephenway 21:43:54

Hello, looking for help with svg <use> tags in Om (dom/svg #js {:viewBox 0 0 100 100"} (dom/use #js {:xlinkHref "/path/to/icon.svg"})) gives me React.DOM.use is not a function on Om Next 1.0.0-alpha.30 with React 0.14

fasiha 21:46:23

@stephenway: <use> tag isn't supported by React: and therefore won't work with Om

blissdev 21:47:50

@stephenway: you can get around it with dangerouslySetInnerHTML which isn’t ideal, but works

jlongster 21:50:48

how do people handle parameterized queries when using db-&gt;tree? there's no way to customize a parameterized piece deep in the query there

artemyarulin 21:53:43

Does anyone have an example of recursive parser for remotes? As far as I understood :remote value has to be either true or AST, isn’t it? So basically I should call parser recursively and then update AST with returned query?

hueyp 22:02:06

the @tony.kay tutorials have parsing examples for recursive parser

artemyarulin 22:04:54

@hueyp: Thank you!

anmonteiro 22:06:51

@tony.kay: let me run your failing case

anmonteiro 22:07:36

but I think patching query-template is usually not the way to go

anmonteiro 22:21:27

@tony.kay: it's a regression of #620, not #612

anmonteiro 22:43:02

@tony.kay: this PR fixes that one

anmonteiro 22:43:52

while we want to save the link's (e.g. '[:a _]) props as :a, the query path still needs to be [:a _]