Fork me on GitHub
#om
<
2016-04-02
>
taylor.sando01:04:15

I think get-query is wrong for when you pass in a class to it

taylor.sando01:04:54

If something implements IQuery, but is not a component, it should just go to line 261, and skip the isFunction check

jimmy07:04:05

hi guys, is {:keys [] in mutation function the same as the key we specify when doing transaction using om/transact! like

(defmethod mutate 'user/logout!
  [{:keys [state parser query ast target] :as env} k params]
  {:value {:keys [:current-user]}
   :action (fn [])})

{:on-click #(om/transact! this `[(~'user/logout!) :current-user])}

jimmy07:04:51

@anmonteiro: thanks for answering. I will create a minimal example later, it quite works for now simple_smile

iwankaramazow08:04:25

@nxqd: the {:keys} in a parser method is there purely for documentation purposes only

iwankaramazow08:04:53

Re-reads happen based on the query itself

jimmy08:04:20

@iwankaramazow: ah, I remember it now 馃槥 It confuses me every time. I asked this question twice already, sorry guys T_T

iwankaramazow08:04:58

The logic behind is: if your team is large enough, somebody else might implement the actual mutation (I think)

iwankaramazow08:04:16

It gives him an idea what is happening at the time

iwankaramazow08:04:32

The docs are pretty ambiguous about this 馃槃

jimmy08:04:34

yeah but do we need as a key in an actual function -_-

jimmy08:04:52

regarding documentation we can put it in comment tag instead.

jimmy08:04:58

btw, thanks for the answer. We will use it as it is for now. note note note xD

iwankaramazow08:04:42

@nxqd: ps do you have an idea how I can set the this.props.children of an om component?

jimmy08:04:28

what are you trying to do ?

iwankaramazow08:04:14

nested routing 馃檲

iwankaramazow08:04:08

No idea if this could even work with query composition, but I'll give it a try

jimmy08:04:15

regarding routing I just use simple om/set-query

jimmy08:04:06

chek the set-query approach

iwankaramazow08:04:42

@nxqd: I have a set-query approach working right now, I'll experiment further

anmonteiro10:04:22

@taylor.sando: it's not wrong, that part is needed for advanced compilation

thiagofm13:04:54

Damn, I'm stuck for over a week in the same problem

thiagofm13:04:35

In those cases, what do you people recommend I should do?

iwankaramazow13:04:58

@thiagofm: taking a long break, going for a run, lifting some free weights afterwards (no machines) & revisiting the problem a week later

iwankaramazow13:04:17

What's the problem?

thiagofm13:04:35

It's with IQuery params. I have the children component Code with: static om/IQueryParams (params [this] {:language nil :repository-full-name nil}) static om/IQuery (query [this] '[{:repository {:query ?language}} {:code {:language ?language :repository-full-name ?repository-full-name}} :language :repository-full-name]) and the parent: (defui Window static om/IQuery (query [this] [(om/get-query code/Code)]) Object (render [this] (dom/div nil "Hello world" (game-window-comp (om/props this))))) There wasn't any dispatch happening to the read :repository

thiagofm13:04:32

I mean, there was, but it was breaking. It was trying to dispatch to the read as {:repository {:query nil}}, which doesn't exist as om/dispatch just get the key

thiagofm13:04:58

So I've written my own "om/dispatch" to in this case, get the key of {:repository {:query nil}} and do the dispatch

thiagofm13:04:11

But now it doesn't get the params(it's always nil)

thiagofm13:04:42

The problem I think is that I'm using "everything": set-query + remote + everything... so I can't really have a sharp idea of what is going on and why

iwankaramazow13:04:59

I recommend starting again with the simplest things: solely a read, then gradually add everything back

thiagofm13:04:14

I have a (om/set-query! this {:params {:language "ruby" :repository-full-name "rails/rails"}}) for example, but it doesn't seem to work

anmonteiro13:04:35

having a valid query will also help

anmonteiro13:04:57

[(om/get-query code/Code)] is not valid

thiagofm13:04:29

What would be valid in that case? I want to get all the queries from the Code component

iwankaramazow13:04:43

Aggregate the query into a join

thiagofm13:04:45

I've tried different things such as: {:code (om/get-query ...)}

iwankaramazow13:04:16

[{:code (om/get-query code/Code)}] should work

thiagofm13:04:47

The problem is that I already have a query called :code

thiagofm13:04:07

I'll name it something else, that could be why it wasn't working

thiagofm13:04:48

Why do I have to also write the reader for my join?

thiagofm13:04:13

All I've wanted was to have my queries as they are in my Code component

anmonteiro13:04:45

@thiagofm: it seems that you still don't understand the basic Om Next concepts. as such, and answering your first question, going through the tutorials again would be my suggestion

thiagofm13:04:19

I went through them a couple of times already, they cover basic examples and usually a bit different from what I want

thiagofm13:04:54

I don't understand why I do need to make a join, when I don't really have to. I already have the queries in my sub component, I just need the data

thiagofm13:04:40

If queries in subcomponents worked, I would never have to do it. It isn't as a sql join. The term join there at least sounds a bit misleading to me

anmonteiro13:04:14

it's a join in the sense that you're joining data in that key

anmonteiro13:04:31

so it's almost a synonym to what a SQL join is

anmonteiro13:04:40

think of it as a modularity thing

anmonteiro13:04:52

let's say you have a clojure program

anmonteiro13:04:16

your core namespace requires namespaces my-project.foo and my-project.bar

anmonteiro13:04:20

it's the same in Om Next

anmonteiro13:04:33

your root component needs to "require" the queries of your sub components

thiagofm13:04:55

I get it better now, thanks. But then what do I do with the reader for that join? I get the value for some query value?

cjmurphy13:04:28

all of the data must come in from the top - into your root component - and it is the total query that works out what this data is. total query is applied to your app state. The top query is always a whole load of joins (and maybe some direct keys as well)

anmonteiro13:04:07

what you do with the reader for that value depends on what you want to do... I'm not the one to say

cjmurphy13:04:16

The read has to go down to the next level - recurse to the keys that are in the query that it has. i.e. a key has a query that is composed of keys.

thiagofm13:04:18

I see. But then the children component will access the result of the parent component query, instead of the queries it provided?

thiagofm13:04:06

Like this: (let [{:keys [repository language repository-full-name ]} (:code (om/props this))] ?

cjmurphy13:04:08

So a read method invokes more reads, using its query. Usually you just call db->tree so it is easy. However with parameters it is hard and I am battling with that at the moment.

anmonteiro13:04:17

@thiagofm: if your Root declares a query [{:foo [:some :other]}], you want to pass (:foo (om/props this)) down to the component

anmonteiro13:04:26

not the whole props

thiagofm13:04:27

@anmonteiro: for that case, it's a sub-sub component, so I pass the whole props because I don't even know what will be the queries that special component needs, but it's good to know that

cjmurphy14:04:19

Your sub-component's query determines what you can pass it.

anmonteiro14:04:06

@thiagofm: you should never pass the whole props down

anmonteiro14:04:35

the point of having queries is that you know exactly what you need to pass down...

thiagofm14:04:08

@anmonteiro: okay, I'll fix it up

thiagofm14:04:30

I think it's a bit misleading that you set up the query in the children component, but it will never function as query of the root component. Maybe it's worth having om/SubQuery or something that would let people know the difference between them

Mikko Koski14:04:46

I can't get the tempids working. I have understood the default merge function should replace the tempids with real ids, if I just call the reconciler send callback with correct format. I'm calling the callback like this: (cb [['todos/add {:tempids {[:id temp-id] [:id 123]}}]]). Still, the id in the state atom is the temp id, not 123. Is the format correct? Is there anything else I should do instead of just calling the callback?

thiagofm14:04:06

@anmonteiro: but thanks a lot for taking your time to explain this to me. Now I have plenty of new things to try

anmonteiro14:04:28

@rap1ds: did you set up :id-key in the reconciler?

Mikko Koski14:04:26

@anmontoire Yeah, I tried that also, I set it to :id-key :id

Mikko Koski14:04:01

In the Quick Start guide it says that the :value map in the mutate function can contain two keys, :keys and/or :tempids. Is that something I should look into?

anmonteiro14:04:47

what you're passing to the callback seems correct

anmonteiro14:04:54

I'm just wondering why it's not a map

Mikko Koski14:04:09

Not sure if relevant, but my Todo component, the ident is implemented like this: (ident [this {:keys [id]}] [:todo/by-id id]) So the app state atom contains list of IDs in todos and then the todo/by-id map.

anmonteiro14:04:10

that's expected

anmonteiro14:04:19

so what happens if you call it like this? (cb {'todos/add {:tempids {:id temp-id :id 123}}})

Mikko Koski14:04:49

@anmonteiro Is this correct? {:id temp-id :id 123} Or should it be {[:id temp-id] [:id 123]} ?

Mikko Koski14:04:00

I tried this (cb {'todos/add {:tempids {[:id temp-id] [:id 123]}}}) and it's still not working. The tempid is still there... I'm starting to wonder if there's something else wrong with my code... hmm..

Mikko Koski14:04:00

This is how I fetch the temp-id:

(let [
        {[children] :children} (om.next/query->ast remote)
        temp-id (get-in children [:params :id])]
I guess that's the right way to do it?

anmonteiro14:04:09

@rap1ds: yes, you're right, typo in my example

Mikko Koski14:04:31

@anmonteiro: Cool! I will look at that. Thanks!

thiagofm14:04:53

@anmonteiro: so, with the previous example of Code(children component) and Window(root comp) and :code join of a couple of queries of the code component. Inside the read :code, what should I do? It seems that I don't have the results of running the query, do I have to call some function inside the read?

thiagofm14:04:45

I can see the params that I set from set-query now: #object [cljs.core.Atom {:val {:language "ruby", :repository-full-name "rails/rails"}}], and also inside the read I have the ast, but the ast doesn't have anything about the just set-query. I can't really fetch anything inside the read as I've expected 馃槥

cjmurphy14:04:35

@thiagofm: Your question is the basically the same as what uwo was trying to do earlier, if I'm not mistaken.

cjmurphy14:04:04

Your sub component has a parameterized query right?

cjmurphy14:04:31

So the key you have made up (for the root component) needs a read. And that is hard to do. I'm in the same boat. Trying to solve the problem uwo has.

thiagofm14:04:35

Inside the read from the root component(:code): My ast has: {:type :join, :dispatch-key :code, :key :code, :query [{:repository {:query nil}} {:file {:language nil, :repository-full-name nil}} :language :repository-full-name], :component haxlife.components.code/Code, :children [{:type :join, :dispatch-key :repository, :key :repository, :query {:query nil}, :children [{:type :union, :query {:query nil}, :children [{:type :union-entry, :union-key :query, :query nil, :children []}]}]} {:type :join, :dispatch-key :file, :key :file, :query {:language nil, :repository-full-name nil}, :children [{:type :union, :query {:language nil, :repository-full-name nil}, :children [{:type :union-entry, :union-key :language, :query nil, :children []} {:type :union-entry, :union-key :repository-full-name, :query nil, :children []}]}]} {:type :prop, :dispatch-key :language, :key :language} {:type :prop, :dispatch-key :repository-full-name, :key :repository-full-name}]} My state has: #object [cljs.core.Atom {:val {:language "ruby", :repository-full-name "rails/rails"}}] As you can see, it isn't merged, queried or anything. I can't see how this becomes something that I would have the result of the queries in my children component

thiagofm14:04:00

@cjmurphy: is this what you have?

thiagofm14:04:32

The sad thing is that there's even a remote in one of the children component queries, so much things going on

cjmurphy14:04:46

When one of us gets it all three will. That's the only good thing at this point.

thiagofm14:04:01

Sounds good

thiagofm14:04:34

@cjmurphy: are your read queries inside the children components running? If I add console.log inside of it, nothing is printed. It seems that the queries aren't getting called anymore

thiagofm15:04:00

Is there any way to call a read from inside a another read and get its result? I guess this is what we're missing, but doing this looks weird

taylor.sando15:04:04

(defn recursive-read [{:keys [query parser] :as env} _ _]
    {:value {:local-value :x
             :other-value (parser (assoc (dissoc env :query)) query)}})

cjmurphy15:04:05

Yes - you call the parser - calling the parser with a query is basically doing a read.

cjmurphy15:04:34

My problem is I don't know where the query parameters are or how to pass them down. Or even if I have to - b/c I don't know how IQueryParams figgers into all of this. (actually I kind of do - just sorting this stuff out...)

cjmurphy15:04:09

Near the bottom of that page, above db->tree seems relevant to us.

thiagofm15:04:12

@cjmurphy: going to take a look

tomjack15:04:12

so do the particular symbol keys in {'app/save {:tempids ...}} matter with the defaults? or just a way to mark :tempids maps?

thiagofm15:04:58

@cjmurphy: can you access the params you set with set-query in the read from the parent/root component?

thiagofm15:04:11

I know like 10 very hacky way to do what I want, but none that are clean.... 馃槥

cjmurphy15:04:37

That's more than I know. I can tell from this kind of code that the params are to be found in the ast:

(defn send-to-chan [c]
  (fn [{:keys [search]} cb]
    (when search
      (let [_ (println "WANT happening: " search)
            _ (pprint (om/query->ast search))
            {[search] :children} (om/query->ast search)
            user-query (get-in search [:params :user-query])]
        (put! c [user-query cb])))))

tomjack16:04:39

I'm playing with nested remote reads and no recursive parsing. building an ast-zipper, walking and finding all the nodes which require remote read. then I have a collection of asts, and {:type :root :children remote-asts} seemed like the natural way to use them

tomjack16:04:40

generally seems strangely limiting that it's expecting only a QueryExpr, not QueryRoot, there. am I confused, though?

tomjack16:04:08

more concrete use case:

tomjack16:04:14

{:foo [{[:remote-bar _] [:bar]}
       {[:remote-baz _] [:baz]}]}

seanirby16:04:51

which one would be more idiomatic? I could either have a top level query [{:ui ...}] in my root component that constructs the entire UI in one read fn. Or several smaller queries for each top level component with a corresponding read fn for each?

iwankaramazow16:04:23

@seanirby: depends on the size of your app, how it is going to evolve, how many people are working on it

iwankaramazow16:04:16

Just do what feels best at the moment

seanirby16:04:01

iwankaramazow: well I wasn't considering it from that perspective. its just a personal project simple_smile. Both have tradeoffs in readability, but I haven't measured the performance difference yet.

iwankaramazow17:04:32

@anmonteiro: is it possible to compose multiple queries under one join? i.e. I'm extending my router to handle nested routes, the idea is to aggregate all queries of children under :root

let [sub-query (reduce #(if-let [query (om/get-query %2)]
                                       (into [] (concat % query))
                                       %) [] components)]
            (into [] (concat [{:route [:router-stuff]}] [{:root sub-query}]))
components is a vector of components that match a given route.

iwankaramazow17:04:13

example result: [{:route [:router-stuff]} {:root [:main/title {:navbar/items [:name :href]} :overview/count]}]

iwankaramazow17:04:33

This should be valid, shouldn't it?

anmonteiro17:04:56

would :main/title be in a different component than :overview/count?

iwankaramazow18:04:43

[:main/title {:navbar/items [:name :href]}] is a component and [ :overview/count] is a query from another one

iwankaramazow18:04:53

I hoped I could join them under :root

anmonteiro18:04:53

then not valid

anmonteiro18:04:29

if you want to join several queries under one key, use a union

iwankaramazow18:04:29

ah ok, thanks for the help, feared this