Clojurians
# om

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

tmorten 00:00:51

Hello all! Does anyone have experience using the Om.next default merge to merge response coming back from a mutation remotely? i.e. using the :value key in the response of a mutation? It seems like my top-level idents will not merge...I was under the impression that if I put a key/value pair into the :value key of the response the default merge will merge it into the app state

anmonteiro 00:26:54

@dnolen: looking at the default-migrate, it reset!s the app-state by running (tree->db (db->tree))

anmonteiro 00:27:14

it seems to me that there's a bug here

anmonteiro 00:27:28

since we store component queries in the state, they'll get blown away

dnolen 00:27:28

@anmonteiro: there might be, but that’s a “GC” step

dnolen 00:27:45

right so we should preserve anything that needs to be preserved

anmonteiro 00:28:21

@dnolen: atm I think it's just the ::queries key. anything else I'm forgetting?

anmonteiro 00:29:19

there might be non-normalized data in the state that users might want to preserve, but I wouldn't worry too much about that since people can always write their own migrate function

dnolen 02:58:09

@anmonteiro: I think that’s it, later we can be careful to only dump tables we know we created

adamfrey 03:41:08

@tmorten what does the “result” from the mutation look like that gets passed to default-merge?

adamfrey 03:58:07

when I do a remote mutation and return a result from the server, the tempid migration is working fine but my server response is getting merged into my app-state if I use the default merge. Like my app state has a migration name as a keyplace/create and the response as a value:
{:keys [:places/list], :tempids {[:place/by-id #om/id["b6d04510-384d-4912-a4eb-64f6791b0b9e"]] [:place/by-id 17592186045425]}}, :om.next/tables #{}}

adamfrey 03:58:43

is that expected? or avoidable in an obvious way?

hueyp 04:02:49

you can filter out symbols before you give it the cb

hueyp 04:02:57

top level keys that are symbols

hueyp 04:03:08

oh nvm

hueyp 04:03:21

withdrawn!

adamfrey 04:05:25

why withdrawn? what didn’t work?

george.w.singer 04:15:25

Is it true that a call to (om.next/reconciler ..) returns an object which -- when dereffed -- returns the current state of your application?

george.w.singer 04:15:53

This seems true when messing around in a REPL

hueyp 04:32:45

@adamfrey: because I don’t know how temp-ids work … I haven’t used them yet so I just remove symbols

tmorten 05:17:45

@adamfrey I also am using tempids, I'll take a look at see what comes in via the response and let you know

tawus 06:00:47

If I have a remote mutation for (om/transasct! [(some/mutation) :update/key]). Should I expect the :update/key be updated after the mutation call is complete?

iwankaramazow 09:12:15

@jlongster: there was/is (???) something weird with context that makes me stay away from it. Something with shouldComponentUpdate, if a component higher in the tree returns false, context doesn't re-render deeper down. You're probably aware of this, but I find this introducing a lot of fragility...

iwankaramazow 09:16:58

@george.w.singer: yes that's pretty much it, you get some extra stuff too like :om.next/queries and :om.next/tables. The tables is a set of the keys in your atom state that represent ident- 'tables'/parts of your global state atom.

iwankaramazow 09:29:55

@tawus: in general if that's the desired result, you should implement your parser that way. Don't expect anything to happen out of the box.

george.w.singer 09:57:15

@iwankaramazow: it also seems that the reconciler has normalized app state data, while the actual app-state doesn't retain the auto-normalized data

george.w.singer 10:00:04

Question: when a component makes calls to (om.next/query ..) via IQuery, is the env that is passed to the parser's reader function set to (i) the root app state, or (ii) the component's local props?

iwankaramazow 10:05:50

what do you mean by the actual app-state data?

iwankaramazow 10:06:05

from what I understand there's a single source of truth: the reconciler

george.w.singer 10:22:33

I mean the root app state fed to the reconciler (which might have been mutated through the reconciler)

bbss 10:23:03

You mean what the components get fed right?

iwankaramazow 10:23:17

or the initial app state?

bbss 10:24:20

You decide with your reads how the components get their data from the normalized format to the tree form that components use.

bbss 10:24:47

So unless you can use db->tree for your reads it's not quite auto-normalized.

bbss 10:25:23

But I am no expert by any means so could be wrong.

bbss 10:27:50

auto-denormalized in case of db->tree actually

george.w.singer 10:27:55

I mean what the components get fed when instantiated via (om.next/factory..)

george.w.singer 10:28:09

Is THAT what is passed to env as the :state key?

bbss 10:28:25

They don't get fed anything, you feed it with props.

george.w.singer 10:28:53

(om.next/factory ..) returns a factory function that is fed with props

george.w.singer 10:29:04

And when you feed that factory function with props

george.w.singer 10:29:24

Does the env draw from those props to source its :state key?

george.w.singer 10:29:42

in the parser's reader function?

bbss 10:30:21

No it draws state from what you supply the reconciler

iwankaramazow 10:30:56

the initial-state gets merged in the beginning

iwankaramazow 10:31:03

after that you can discard it

iwankaramazow 10:31:08

everything comes from the reconciler

george.w.singer 10:31:13

What's weird is that I see in lots of tutorials (query ...) declarations that draw directly from props.

george.w.singer 10:31:55

Are the props just fed in to immediately render a value?

george.w.singer 10:32:24

and then the (query ...) call is to signal "these props are stateful, and might change?

bbss 10:33:28

The root component (the one the query composes to) gets fed props by the reconciler, from there it is up to you to split the right data into props for non root components.

iwankaramazow 10:35:04

probably the [(points/increment ~props)]`

iwankaramazow 10:35:32

props is an arbitrary name here

iwankaramazow 10:36:01

it just means it gives the current value for name & points to the mutation

iwankaramazow 10:37:26

in fact you could only pass the :name, look the :points for that name up in the state (from the env), and update it

bbss 10:39:49

is there a convenience function to easily merge in an existing db state with a diff db state, or do I have to manually update all the links?

iwankaramazow 10:41:10

what do you mean with diff db state?

iwankaramazow 10:44:01

without overwriting existing stuff?

bbss 10:44:31

say I have :task/list [:task/by-id 123] :task/by-id {123 {:id 123 :name "I am a burden"}} and I use tree->db and to create a new task and end up with :task/list [:task/by-id 456] :task/by-id {456 {:id 456 :name "I am a burden too"}}

bbss 10:44:46

yes, without overwriting

bbss 10:45:24

do I manually have to conj the id to task/list and update the :task/by-id map?

iwankaramazow 10:46:55

if this is local only, yes.
If you merge incoming remote data, then you can use (defn custom-merge-tree [a b] (if (map? a) (merge-with into a b) b))

iwankaramazow 10:47:17

and then pass on your reconciler :merge-tree custom-merge-tree

bbss 10:47:39

hmm. okay, interesting.

bbss 10:47:47

hoping to get to the remotes stuff soon

iwankaramazow 10:49:06

I started out by putting my navbar on the server :joy:

iwankaramazow 10:49:31

just fetching a list of nav-items that gets normalized on the client with idents

bbss 10:50:30

I am doing something pretty simple first too. Making something to track my activities, only added difficulty is I am using a query with recursion.

bbss 10:53:48

{:name :some-task :should-take (minutes 5) :sub-tasks [{:name "something that has to be done during the task" :should-take (minutes 2)}]}

bbss 10:54:12

hoping to somehow use web audio to bug me to track the tasks so I can get better at estimating tasks.

iwankaramazow 10:55:02

cool :simple_smile:

iwankaramazow 10:57:10

that mutation just swaps everything on the local state

bbss 10:58:52

Thanks

george.w.singer 11:17:51

In the "Components, Identity, and Normalization" tutorial (https://github.com/omcljs/om/wiki/Components%2C-Identity-%26-Normalization), there is a call to (query [this] '[:name :points :age]) within the Person component definition. Yet there is never a parser read function defined which takes any of those keys (:name, :points, :age). Isn't this a problem?

george.w.singer 11:18:37

Why isn't* this a problem?

bbss 11:20:34

Because only the root key read gets called, after that it is up to the read function to call the parser recursively if you want to split up your read.

bbss 11:20:56

-is my impression, please let me know if I am wrong-

iwankaramazow 11:21:32

(defn get-people [state key] (let [st @state] (into [] (map #(get-in st %)) (get st key))))

iwankaramazow 11:22:22

this functions makes sure everything gets read

iwankaramazow 11:23:25

As @bbss says, only the root keys get read, in this example :list/one :list/two

iwankaramazow 11:24:04

The parser dispatches on :list/one :list/two

iwankaramazow 11:24:28

As you can see in the tutorial, they both return {:value (get-people state key)}

iwankaramazow 11:24:52

the function get-people makes sure every key gets read

iwankaramazow 11:27:36

for :list/one you'll first look up (get st :list/one) with get-people

iwankaramazow 11:27:51

that gives you
[[:person/by-name "John"] [:person/by-name "Mary"] [:person/by-name "Bob"]]

iwankaramazow 11:28:25

then the map function applies #(get-in st %) to the vector above

iwankaramazow 11:29:24

basically it'll do (get-in st [:person/by-name "John") (get-in st [:person/by-name "Mary") (get-in st [:person/by-name "Bob")

iwankaramazow 11:30:04

and st contains
:person/by-name {"John" {:name "John", :points 0}, "Mary" {:name "Mary", :points 0, :age 27}, "Bob" {:name "Bob", :points 0}, "Gwen" {:name "Gwen", :points 0}, "Jeff" {:name "Jeff", :points 0}}

iwankaramazow 11:30:46

the return value gives you {:name "John", :points 0} for [:person/by-name "John"]

iwankaramazow 11:31:16

in the tutorial the query '[:name :points] is redundant

iwankaramazow 11:31:21

it doesn't get used

george.w.singer 11:43:38

So when (query ...) is called

george.w.singer 11:43:47

does it automatically send a read request to the parser?

george.w.singer 11:44:14

And then -- in this case the parser says "I already have the information about that read, and I got it another read, so here is the value you're looking for"

thiagofm 11:48:36

@iwankaramazow: Just saw the https://github.com/awkay/om-tutorial link -- good stuff! I wish I knew about this before. Perhaps add to the wiki? (maybe it was there but I didn't see it...)

thiagofm 11:48:47

Would've made my life way easier

iwankaramazow 11:52:09

@thiagofm: yea that tutorial is a goldmine :smile: Everything you need is in there I'm not in charge of the wiki...

iwankaramazow 11:53:44

@george.w.singer: the reconciler will send the query from your Root Component through the parser

iwankaramazow 11:54:04

it's up to you to pick that query apart

iwankaramazow 11:54:17

the top level keys get recursively parsed though

iwankaramazow 11:54:34

there's nothing shady going on here, it's basic recursion

thiagofm 11:54:59

It was probably a lot of work, great stuff

thiagofm 12:06:37

@iwankaramazow: do you think it's wrong to query something inside a mutate method? I have a case where it my mutation query depends on other attributes, which are really about another component

thiagofm 12:07:24

(I'm using datascript)

iwankaramazow 12:09:52

Most mutations happen based on some attributes (that might be or not be available at a component)

iwankaramazow 12:10:27

For intercomponent comunication I use graph-style queries

thiagofm 12:10:32

I could still query this data in the component level, but this would be just passed down to the mutation

iwankaramazow 12:10:34

a la 'thinking with links'

iwankaramazow 12:11:09

that's the approach I'm doing now

iwankaramazow 12:11:25

but the state is available in your env at the mutation in the parser

iwankaramazow 12:11:30

so you can get it from there

iwankaramazow 12:11:40

mutations have to be side-effect-free though

iwankaramazow 12:11:52

not sure if deref'ing your state is pure

thiagofm 12:13:38

I'm making a simple game, so let's say the player can buy a bunch of upgrades. To display his total money he made in the current tick/second, I can either query this data in the component(What he bought isn't getting displayed in that component or is anywhere related) and pass it to the mutation that does this calculation and updates the total money, or query inside the mutation. Querying inside the mutation kind of help, as it's pretty clear what's happening, but yeah, dunno if this is functional :disappointed:

thiagofm 12:15:37

@iwankaramazow: what do you mean by side-effect free? I'm only transacting inside it, so it's like a side effect, no?

iwankaramazow 12:16:34

given the same arguments you should always have the same result

thiagofm 12:17:12

That is true, it's not sideeffect free :disappointed:

iwankaramazow 12:17:17

a simplistic example, if you (println "test") that isn't pure

iwankaramazow 12:17:24

inside a mutation

iwankaramazow 12:17:43

for all we know your computer may crash and we don't see "test"

thiagofm 12:18:00

So if I transact inside it, it isn't side effect free anymore right?

iwankaramazow 12:18:29

transact inside a mutation?

iwankaramazow 12:18:57

no, the thunk has to be side-effect free at :action in your parser

iwankaramazow 12:20:36

you probably shouldn't transact inside a mutation, I'm not sure though

iwankaramazow 12:21:12

that's datascript

iwankaramazow 12:21:23

yea that's valid

iwankaramazow 12:22:37

looks pretty ok to me

iwankaramazow 12:22:40

but I'm no expert

thiagofm 12:23:17

But yeah, I think I kind of get it now. It's a better idea to query stuff in the component and have in the mutation perhaps only the transaction(and some pure function call if that's the case). Otherwise I'm not passing arguments to that mutation and it wouldn't feel side-effect free or pure, as by passing different arguments, i get a different result transacted everytime.

thiagofm 12:23:29

Does this make sense?

thiagofm 12:24:19

{:action (fn [] (let [[id total] (first (d/q '[:find ?id ?e :where [?id :lambdas/total ?e]] (d/db state))) per-second (ffirst (d/q '[:find ?e :where [_ :lambdas/per-second ?e]] (d/db state))) next-second-total (lambda-coins/next-second per-second)] (d/transact! state [{:db/id id :lambdas/total (+ total next-second-total)}] :values)))})

For example here I query [id total] and per-second. This could've been done in the component side

iwankaramazow 12:24:19

apart from the side-effect-free stuff (which I'm totally not sure about) , it's indeed a better idea to keep your mutations only about transactions

thiagofm 12:26:14

Thanks for you help, that was very enlightening :simple_smile:

iwankaramazow 12:29:57

pure or side-effect-free is only about 'given the same input of a function, you always get the same output'

iwankaramazow 12:30:16

the input for that function may differ, but the result is always the same for a given input

iwankaramazow 12:32:08

I'm totally not sure if a read of your datascript db may happen in a mutation

iwankaramazow 12:32:37

someone should shed some more light on this, help? :smile:

thiagofm 12:32:51

I wonder what (d/transact!) would return, but I guess if I send all the needed parameters to update the value needed, it's would have less side-effects

thiagofm 12:34:19

Makes sense to query this in the component. I'm still wrestling with the whole concept. Before I was using reagent and even though you can probably avoid all the side-effect you want if you write things well, my code was full of state

thiagofm 12:35:05

Om next seems to take this idea of side effect-free to another level. The idea for example to my root component have all the necessary queries from the children components was neat, but took me some time to figure out why it was like this

iwankaramazow 12:37:36

I've never used Reagent

iwankaramazow 12:38:13

side effect-free is all about making state management more predictable and reliable

iwankaramazow 12:38:32

this is a huge bonus when your state is complex

iwankaramazow 12:39:08

David Nolen had some pretty awesome revelations, when designing Om :smile:

danielstockton 12:43:45

@thiagofm: I guess you don't use set-query anywhere? I'm interested how people make that work with datascript

nxqd 13:54:13

hi guys what is the proper way to use om computed. What I'm trying now is
(om/computed props {:text "something"}) (prn (om/get-computed this))

I got nil in return

iwankaramazow 14:10:35

``` (defui Component Object (render [this] (let [computed-props (om/get-computed this)] (dom/div nil "stuff"))))

(def component (om/factory Component)) ```

iwankaramazow 14:11:41

(component (om/computed props {:text something}))

iwankaramazow 14:12:45

@nxqd: that should do it

thiagofm 14:16:59

@danielstockton: I just have to use set-query in my main compontent, example: https://github.com/thiagofm/haxlife/blob/master/src/cljs/haxlife/components/window.cljs#L35

thiagofm 14:17:38

And then I pass om/props to children components and have the query on each separate component

thiagofm 14:18:03

I don't know if this is right, but after talking with a couple of people from here this is how I was able to make it work

thiagofm 14:20:08

This is also my first take on om next, I've decided to use datascript from the beginning so I can learn how to query datomic while I write this project. After I knew about that get-query usage I feel like I'm able to do whatever I want regarding to that, now I'm more like reflecting on how to use it right.

thiagofm 14:31:33

So I also don't know what is the way of doing it without using datascript :simple_smile:

danielstockton 14:40:14

This is slightly different, that's get-query not set-query

danielstockton 14:40:57

If you're updating your queries in runtime with set-query!, you'll eventually discover that om doesn't work with datascript unless you make some modifications

danielstockton 14:41:21

om sets a ::queries key in the app-state and it expects the state to be an atom

danielstockton 14:41:59

I'm in the same position as you, I'd rather learn datomic/datascript than worry about normalization

iwankaramazow 14:55:05

@danielstockton: there isn't much about normalization ;) om/db->tree takes care of the heavy lifting :smile:

thiagofm 14:56:27

@danielstockton: oh, I get it. Yeah, with datascript I don't think I need to use it

iwankaramazow 14:57:00

@thiagofm: how do you implement routing?

danielstockton 14:57:06

you might want to, for example it seems like the preferred method of routing is using set-query!

danielstockton 14:57:09

although there are alternatives

danielstockton 14:57:35

im using union queries for now

danielstockton 14:58:41

@iwankaramazow: true, but i like that om promises to separate state from everything else, which isn't quite true at the moment

danielstockton 14:59:08

and i like datascript, you can do some powerful stuff that would be harder to implement with atoms

iwankaramazow 14:59:23

@danielstockton: never thought of it that way, but I see what you mean

danielstockton 14:59:53

i think it will change in future, it's not hard to make set-query state agnostic

iwankaramazow 15:00:02

I plan to experiment with datascript once this side project is pretty much finished

danielstockton 15:00:04

and provide a default implementation for atoms

iwankaramazow 15:00:57

are there any other problems with datascript atm?

iwankaramazow 15:01:04

in relation to Om.Next*

danielstockton 15:01:20

i think that's the main one, there are other pros/cons

danielstockton 15:02:36

tempids is another con, you have to either have a separate attribute which you can update or delete temporaryclient-side datums and re-transact datums from a remote

danielstockton 15:03:08

and i think a pro is that deletes are easier, i don't have to worry about deleting from multiple places

danielstockton 15:03:31

dunno if tempids is a real con, just requires a different approach

iwankaramazow 15:03:45

Interesting

iwankaramazow 15:04:10

the way I'm handling deletion now is in one place

iwankaramazow 15:04:32

I just delete the reference in a list for example

iwankaramazow 15:05:06

that is, the entity keeps existing in the :item/by-id portion of my state

danielstockton 15:05:24

right, in case its referenced elsewhere

danielstockton 15:05:29

and it exists indefinitely?

danielstockton 15:05:34

or you have some cleanup methods

iwankaramazow 15:06:21

for the moment most code is 'cave-men-style', no cleanup methods

iwankaramazow 15:10:05

ps: do you have a Datomic backend along the datascrip?

danielstockton 15:10:20

yeah, im just toying also, things will become clearer as more people create serious projects with it

danielstockton 15:10:56

yep, datomic backend

danielstockton 15:11:22

so i send the datums from the server and just transact them, it makes some things easier

iwankaramazow 15:12:26

so the integration datascript/datomic is pretty smooth?

danielstockton 15:14:00

so far but as i said, just toying at the moment

danielstockton 15:14:08

might be issues i haven't come across yet

danielstockton 15:15:04

having datomic also simplifies the parser, you can pretty much take the om query and use it as pull syntax

iwankaramazow 15:16:09

Definitely, I switched my sql database to datomic

iwankaramazow 15:16:26

and I have to say I'm pretty amazed about how much less work I have to do...

danielstockton 15:17:24

datomic seems great for 95% of typical use-cases and i imagine it's easy to write parsers for the other 5% that you might want to store elsewhere

danielstockton 15:18:01

reports or whatever that is

iwankaramazow 15:20:38

The only problem is I can't even bring this stuff to my team at work

iwankaramazow 15:21:39

Clojure(script) & datomic is too much of a leap for most people

thiagofm 15:22:55

@iwankaramazow: I'm not doing routing and I just have intentions of doing just a couple of requests to the backend, most of the game is client side

thiagofm 15:23:39

Only after I'm done with this project I'll try to explore more how to do a SPA

thiagofm 15:24:24

Yeah, I also don't work with clojure, mostly ruby, mutable stuff... There aren't many jobs, it's hard to find one

danielstockton 15:26:11

datomic is actually a perfect fit for my work i think, i just dont have the confidence to fully push it yet which is why i want to experiment in toy projects

thiagofm 15:26:13

I find datomic very awesome :simple_smile: It's great to be able to use datascript and learn a bit more about querying on it

jlongster 16:24:33

@iwankaramazow: yes, context makes shouldComponentUpdate more ambiguous, but only if the context ever changes. Context is great for exposing singletons throughout the whole app, and redux does that to connect everything to the store. We should be fine using it to connect the reconciler and indexer because you can't "switch them out" in the middle of your app

jlongster 16:25:11

or you could always return true in sCU if the context has changed at all, thus everything would rerender, but we should be able to just ignore context in there

nxqd 16:39:05

@iwankaramazow: hmm, I think I can use (om/computed) to store computed values ( cache ) while working within the component not passing from outside.

iwankaramazow 18:08:41

@jlongster: thanks for the clarification, I had a lot of problems with Redux trying to implement int18n trough context.

iwankaramazow 18:10:06

@nxqd: any luck yet?

tony.kay 20:46:00

@dnolen: Working on a support VCR viewer for app state history. I'd like to include client timestamps in the history. Wondering if you would accept a PR for tacking a timestamp onto the app-state entries in history as metadata?

jlongster 21:00:16

I have tempid migration working but I need to generate idents that map to a local table, like [:transaction/by-id 1]. How is the server supposed to know what the local id key should be for that id?

dnolen 21:02:13

@tony.kay: sure!

george.w.singer 21:03:10

Is my bit understanding of om.next queries correct? Here it is:

  1. Only the root query actually gets read by the parser; the results of this root query read are then fed in through the props of its child components.
  2. The non-root component queries -- known as "fragment queries" -- aren't actually read by the parser; however, they are used behind the scenes for properly re-rendering your UI when state changes.

Is this correct?

jlongster 21:08:53

@george.w.singer: the non-root queries are still read by the parser, but it's up to you if you recursively call the parser, use db->tree to execute the query, or do something else

george.w.singer 21:09:41

You mean place db-tree within your read function?

george.w.singer 21:11:48

"Om only looks for the query on the root component of your UI! Make sure your queries compose all the way to the root! Basically the Root component ends up with one big fat query for the whole UI, but you get to reason about it through composition (recursive use of get-query). Also note that all of the data gets passed into the Root component, and every level of the UI that asked for (or composed in) data must pick that apart and pass it down." -- https://awkay.github.io/om-tutorial/#!/om_tutorial.E_UI_Queries_and_State

george.w.singer 21:11:58

That's where I got (1) and (2) above.

jlongster 21:12:57

yes just the root query is the only thing passed to the parser, and it executes the whole entire query

george.w.singer 21:15:53

So the child queries don't actually have any tangible effect when your app starts?

george.w.singer 21:16:11

They are just using the props fed into them by the fat query read from the parent?

george.w.singer 21:17:28

Ok, last question on this :grinning: : Why call them "props" if they are stateful?

george.w.singer 21:18:00

The child components get fed their queries from the root component, but that data is subject to change later on

george.w.singer 21:18:40

Is it just a carry-over from react to refer to them as props?

dnolen 21:19:03

@george.w.singer: no

jlongster 21:19:36

they are still just props fed in from something, whether it's the parent component or the indexer doesn't matter

dnolen 21:21:17

@george.w.singer: the point is to maintain the semantics that the root component is a function from props -> render tree

dnolen 21:21:39

that the root of the application is stateful doesn’t have any bearing on the root component acting more or less as pure function

george.w.singer 21:24:28

:+1: Thanks :slightly_smiling_face:

iwankaramazow 21:30:17

@jlongster: just curious, but why no uuid?

jlongster 21:30:53

@iwankaramazow: not sure what you mean

iwankaramazow 21:32:09

'How is the server supposed to know what the local id key should be for that id?' Is this a normal use case?

iwankaramazow 21:32:42

it seems logical to generate unique random id's, merge those back in

iwankaramazow 21:32:54

om takes care of the rest ?

iwankaramazow 21:36:06

(I might have misunderstood your question..)

jlongster 21:37:46

no, I mean the local table key

jlongster 21:38:42

if an ident is [:foo/by-id 1] and I add a new item, I add [:foo/by-id (om/tempid)] and then later replace it, but for it to be replaced the server has to return an ident with the same key like [:foo/by-id 2]

jlongster 21:39:23

I mean, the client can send the name of the key to be used as well, but all of the examples I've seen hardcode something like :db/id

iwankaramazow 21:39:52

Ah ok, good point

iwankaramazow 21:40:22

I'm just starting with tempids, I'll report back if it works

iwankaramazow 21:42:26

from Tony's tutorial: On the server, convert tempids to real IDs. Return a :tempids map from the server. Keys are tempid ident, the values are the new real ID idents.

jlongster 21:42:59

right, I have that all working

jlongster 21:43:19

but right now I have to hardcode :transactions/by-id in the ident, but there are other idents like :accounts/by-id that need to work too

iwankaramazow 21:44:36

Just looked at the copaste example

iwankaramazow 21:45:05

seems sending them as params looks like the only solution

jlongster 21:48:34

yeah, that works

dnolen 22:01:35

@anmonteiro: reviewing your PR, I’d like to do some renaming here to make the code clearer - I can’t say I like how I named things before and now that the logic is going to get a little more sophisticated my bad naming choices are becoming apparent.

dnolen 22:01:44

I’ll leave comments in the current PR.

anmonteiro 22:02:08

@dnolen: perfect. I am also not happy with the naming

anmonteiro 22:02:22

but I couldn't really find better alternatives

dnolen 22:02:35

I think local is getting overloaded here

anmonteiro 22:02:44

you know, computer science & naming for one, not being a native speaker for seconds :simple_smile:

dnolen 22:02:46

in most cases I think we should just say get-instance-query

dnolen 22:03:06

local just doesn't mean anything

anmonteiro 22:04:31

so get-local-query-data should also be get-instance-query-data?

anmonteiro 22:04:46

just saw your comment

dnolen 22:05:07

or actually maybe since we’re already using component to always means instance we can just be more consistent about it

iwankaramazow 22:12:31

I noticed there's a tempid?available in cljs om.next but not in clj om.next.server...

iwankaramazow 22:12:48

Totally not a priority, but might be nice in the future

iwankaramazow 22:16:30

Oh nevermind

iwankaramazow 22:16:46

:face_with_rolling_eyes:

dnolen 22:27:57

@anmonteiro: also get-local-query is a bit strange since it also checks component?, I’m not sure I understand the docstring.

anmonteiro 22:29:14

@dnolen: the docstring definitely needs changing too

anmonteiro 22:29:27

basically this is the old get-query

anmonteiro 22:29:34

which falls back on the class

anmonteiro 22:30:20

I meant local in the sense that it doesn't leverage the indexes

dnolen 22:30:22

@anmonteiro: ah, and the new get-query uses the indexer

anmonteiro 22:30:49

but then again, local doesn't really mean anything :stuck_out_tongue:

dnolen 22:30:55

@anmonteiro: ok

dnolen 22:32:33

@anmonteiro: in the dev cards bit you invoke get-local-query is this intentional? Just testing something?

anmonteiro 22:34:44

@dnolen: unintentional. remains from a previous version where I thought get-local-query had to become part of the public API

anmonteiro 22:35:05

I've also noticed that I'm calling it unnecessarily in the build-index* function.

anmonteiro 22:35:09

needs changing

dnolen 22:36:25

@anmonteiro: k I’m leaving comments on all these cosmetic things first, then let’s do another PR and I’ll review a second time (good to read over this at least twice on my end)

anmonteiro 22:36:57

@dnolen: sounds good

anmonteiro 22:48:03

@dnolen: I didn't understand if you had finished commenting or still going through it

dnolen 22:57:38

still going through it