Fork me on GitHub
#om
<
2016-03-08
>
tawus04:03:30

I see a few discussions related to datascript and om.next. There are a couple of demo applications but all of them client only apps with no server side integration. Are there any issues I should be aware of before I go down this route ?

seanirby04:03:58

im trying to make sense of the om next todomvc example. currently i've set up everything so that I can send a query to the server and get the correct response back in the callback I gave to send. I verified that I can translate it from transit to json. I now expect this data to be properly represented in my app-state, but its not. I'm looking at the state key in the env argument that the root read function receives and it is malformed. I'm not sure what to do at this point, any ideas?

tawus04:03:30

Are you using normalization ?

tawus04:03:06

when you say malformed, does it mean not normalized ?

seanirby04:03:34

i can see that the state is normalized but I'm expecting two todo entries

seanirby04:03:40

but only one is there

seanirby04:03:09

#object [cljs.core.Atom {:val {:todos/list [[:todos/by-id nil] [:todos/by-id nil]], :todos/by-id {nil {:db/id 17592186045419, :todo/completed false, :todo/title Walk dog}}, :om.next/tables #{:todos/by-id}}}]

tawus04:03:53

you can also use the repl (if you are using sidecar) and output @reconciler.

tawus04:03:44

It seems your ident might have some issues.

seanirby04:03:19

yeah the reconciler is bad too

seanirby04:03:23

i will double check the idents

tawus04:03:45

or may be your query for TodoItem does not mention :db/id. Just guessing simple_smile

seanirby05:03:09

tawus: I think you're right. is it normal for it to be this confusing ? simple_smile

tawus05:03:26

@seanirby: Hahaha.. absolutely!

seanirby05:03:53

well, you were right on the money. I was using (let [{:keys [id] ..}] when it should have been db/id

seanirby05:03:08

thanks so much

tawus05:03:05

np. Glad I could help.

seanirby05:03:22

tawus: do you know of any other resources for learning besides the github docs and awkay's tutorials?

tawus05:03:33

There are a few articles here http://anmonteiro.com/

cjmurphy05:03:04

@seanirby: By the way there's a pretty simple library that picks up those kind of mistakes for you: https://github.com/chrismurrph/default-db-format. I wrote it because I make them quite often.

seanirby05:03:54

cjmurphy: awesome, thanks

cjmurphy05:03:19

With it you don't have to think "oh maybe I should look at @reconciler" - it will tell you when the problem first happens, and pinpoint where it is.

tawus06:03:09

@cjmurphy: It gives me Not normalized in tables problems: for code/name which is a string.

cjmurphy07:03:49

Hi @tawus. The rules for what is acceptable include a String (nil? number? string? boolean? ident? vec-of-idents? etc all acceptable as table data values). That sounds like a bad error message thou. You can exclude top level entries that are not supposed to be inspected. Also there is also an 'escape hatch' function you can supply for saying what is acceptable - but that is only intended for complex objects. Would you be able to submit an issue with the result of @reconciler? Components and initial data would be good too but I can hopefully work them out if its not too huge.

tawus07:03:33

thanks. I’ll do that when I get time. BTW it is really useful.

cjmurphy07:03:05

oh great thanks - only been used by me so far I think. I want it to save time thou!

tawus07:03:18

It gave me very useful pointers to my problems. It is definitely useful.

tawus08:03:39

I can create an issue, if it is really a bug. May be my state is an issue which it is correctly depicting.

cjmurphy09:03:49

@tawus: It was a bug. My list of things that are real data didn't include keyword?. I'll release a new SNAPSHOT in a moment but for now you can just put :acceptable-table-value-fn? (fn [v] (= keyword? v)) into the input hashmap, which I'm guessing you've already used for excluding :app/route and :om.next/tables. Will private msg you...

shem12:03:16

strange. i have this om-0.8.8 project, works nicely, haven't touched it for three months and now advanced compilation dies with stack overflow error

shem12:03:26

something in the tooling apparently changed and broke it

matthavener12:03:40

cjmurphy: devcards.. I can add a full ns form of youd like to try it 😄

tawus15:03:39

Can db->tree handle parameterized query ?

matthavener15:03:03

tawus: yeah, it just ignores the params

matthavener15:03:29

right? params have no effect on tree building, they’re just for changing the effects of read/mutate functions

tawus15:03:56

So how do you handle such a situation ? Say When you are trying to filter a list by some parameter and the whole list is on the client side

tawus15:03:08

One way would be to just do it in component lifecycle

matthavener15:03:38

you want to filter a list but using a short reader that just does get-in with db->tree ?

matthavener15:03:31

you could always recurse into the parser to handle that read with your params to filter there

matthavener15:03:45

i’m pretty new to om.next though so take any of my advice with a large grain of salt 😛

cmcfarlen15:03:57

@tawus Keep the full list in one key in the state and have a reader handle a filter key that takes params and does db->tree on the full list key, filters the result and returns the denormalized filtered data. The reconciler will denormalize it and cache the filtered list in the state under the filtered key.

cmcfarlen15:03:11

When you change the params, the reader should get called again to update the filtered list

cmcfarlen15:03:58

I'm also new to om.next, but I think I would try something like that

tawus15:03:28

@matthavener: yes I was thinking of using just db->tree.

tawus16:03:01

@cmcfarlen: that is what I am currently doing! But I think it should be supported out of the box by db->tree

seanirby16:03:25

hi all, why is he using postwalk here? won't you end up recursing through the entire :db-before and :db-after values? https://github.com/swannodette/om-next-demo/blob/master/todomvc/src/clj/todomvc/server.clj#L42

anmonteiro16:03:40

@seanirby: no, they're just references

seanirby16:03:26

@anmonteiro: thats what I originally thought, but i dropped in a println in that fn and thats what it seems to be doing.

kenbier17:03:59

@tony.kay thanks, i ended up using your approach and it most definitely works with c3 as well simple_smile thanks for the input

kenbier17:03:58

why does a parent rerender when it passes a computed callback to the child, but not if the child invokes the same function directly (without it being passed in)? the function changes some child data, but in the value map I instruct for a read of the parent data to happen. is it not possible without passing in a callback?

kenbier17:03:09

for ref here are my mutate fn and simple state

(defonce select-test-atom (atom {:selector-one {:value   "1"
                                                :name    "name"
                                                :options options}}))

(defmethod mutate 'selector/update-select-value
  [{:keys [state]} key {:keys [value]}]
  (inspect state)
  {:value {:keys [:selector-one]}
   :action #(swap! state assoc-in [:selector-one :value] value)})

tomjack17:03:01

the docs say that the :value has no effect on rerendering; not sure if this is your problem

hueyp17:03:52

if my memory serves me the component that calls the tx gets queued to re-render always, the rest are via read values in the tx

hueyp17:03:02

calls the tx being the this

kenbier17:03:21

@hueyp: hmm perhaps my query fn is wrong? in theory it thought it should work

hueyp17:03:53

the reads I’m talking about are the read keys in the tx, e.g. [(todo/toggle) :todo/completed?]

hueyp17:03:07

so :todo/completed? schedules components that have that prop to re-render

hueyp17:03:27

this is from memory … I haven’t looked at the source in awhile 😜

kenbier17:03:37

well that fixes it! thanks for clearing that up

cmcfarlen17:03:12

When I merge in some new state, existing entities in the same table are being removed and replaced with the new. The refs to those removed items are still in the state, just no longer in the normalized table.

cmcfarlen17:03:39

I have created a small test case that demonstrates this problem.

kenbier17:03:42

in on-change function just submitted the value to be changed, which makes me think ill need to pass this in if i want the parent to render. that or pass the keys to rerender to the child, which seems worse

bplatz18:03:29

@anmonteiro: I have a bug that was introduced at commit a8559af 'OM-630: migrating tempids blows away component queries'

bplatz18:03:42

When using datascript at least, as state, and a custom :merge-tree, It introduced an error.

bplatz18:03:57

One sec... let me get the error again... need to roll to that commit.

bplatz18:03:50

Uncaught Error: conj on a map takes map entries or seqables of map entries

bplatz18:03:37

Seems it has to do with the change to use merge*, and then immediately after you use merge which is now a different function. I tried modifying the second merge figuring you just forgot to change that one too, but that produces a different error. I don't understand enough of the internals there to help much more.

bplatz18:03:57

But I'm quite sure it has to do with reverting to a different merge, when a custom merge is provided.

anmonteiro19:03:41

no, I didn't forget to change to merge*

anmonteiro19:03:48

it's supposed to be cljs.core/merge

bplatz19:03:06

Yeah, I just figured that out.

anmonteiro19:03:15

the problem is that we store the queries in the state map

anmonteiro19:03:28

when it's a datascript connection it doesn't know what to do

anmonteiro19:03:08

this will be solved once we add support to set-query! for datascript users

bplatz19:03:05

I'll just be sure to use a prior commit for now.

cmcfarlen20:03:40

Ok, I think I figured out my issue with the unexpected merge! result. If I make the :merge-tree fn be:

(defn my-merge-tree
  [a b]
  (if (map? a)
    (merge-with merge a b)
    b))
then I get the expected results. The default just does a single merge so the next state will overwrite the previous.