Fork me on GitHub
#om
<
2016-02-02
>
nano00:02:08

nevermind, apparently [:input {:type "number"] is a thing.

nano01:02:09

What's the purpose of {:search ast} here https://github.com/omcljs/om/wiki/Remote-Synchronization-Tutorial compared to just passing {:search true} ?

hueyp01:02:27

I think in that case its equivalent, but earlier in the tutorial the parser was modifying the ast per-remote

hueyp01:02:43

thats my guess simple_smile

jimmy02:02:43

hi guys how to debug the error No queries exist for component path

cjmurphy04:02:00

@nxqd: Did you get past that error message? All I could say is trial and error playing around with the queries, especially making sure that logically the components are feeding props down, and the keys of the props are matched by the queries.

jimmy04:02:21

I find that my indexer doesn't index component path when it first initialised. I switch child component ( direct first child component ) dynamically based on root component query

jimmy04:02:30

I have a case that it works is when I change to another component ( changing dynamically by changing the query ), then go back to the first one, now there is no more error.

cjmurphy06:02:56

I just got the same message: Uncaught #error {:message "No queries exist for component path (om-alarming.core/App om-alarming.components.nav/TabButton)", :data {:type :om.next/no-queries}}

cjmurphy06:02:14

I noticed that in between the components App and TabButton there was another component that did not need to be a component. It had a rendering method but no queries. So I turned it into a function and that got rid of the message.

nano07:02:44

@nxqd I get that when try defonce/:once all the things for keeping state over figwheel updates. routing that breaks I think. Gave up on that for now.

lfn307:02:25

Does anyone know if db->tree is supposed to work with recursive queries? It’s giving me a stack overflow.

lfn307:02:33

Happy to provide more specifics or a minimal repro if it is meant to work.

lfn307:02:07

(this is on the latest snapshot, btw)

cjmurphy07:02:18

@lfn3: I put db->tree in most of my read defmethods so I don't have to do the recursion. In fact they all look the same now - practically all of them just call that function because the state is completely normalized with Idents and db->tree can thus recursively read any value. (I don't have complex queries yet - nothing parametrized, no unions).

lfn307:02:57

Right yeah the issue I’m having is with queries containing

lfn308:02:47

Like components that nest themselves like:

(defui item
  static om/Ident
  (ident [_ {:keys [id]}]
    [:task/by-id id])
  static om/IQuery
  (query [_]
    '[:id :text {:children ...}])
  Object
  (render [this]
    (let [{:keys [text children] :as props} (om/props this)]
      (dom/li nil text
              (when (seq children)
                (dom/ul nil
                        (for [child children]
                          (item-factory child))))))))

cjmurphy08:02:59

That doesn't seem too special. Lots of components nest like that I would think. Perhaps your state is not fully normalized??

cjmurphy08:02:12

I'm assuming your read looks like this:

cjmurphy08:02:18

(defmethod read :children
  [{:keys [state query]} key _]
  (let [st @state]
    {:value (om/db->tree query (get st key) st)}))

lfn308:02:21

Exactly like that, even.

cjmurphy08:02:20

I only have two types, the other is even simpler, and is the :default.

cjmurphy08:02:51

Anyway (pprint @reconciler) will allow you to check your state, to check that it is fully normalized, in which case db->tree should work for you.

lfn308:02:20

Yeah it seems like a common case to me as well. The data looks normalized to me (I added a prn to the parser, to emit the state)

cjmurphy08:02:30

Could you have an Ident that refers to an Ident and so on and then refers back to one of the original Idents - so a recursive loop like that?

cjmurphy08:02:01

(just guessing now)

lfn308:02:40

Nah, there’s just 3 things in the list - two top level items and one child.

lfn308:02:10

I can see a devcard in the om src that replicates my case pretty exactly so I’m gonna try and get that working.

cjmurphy08:02:54

'two parents to one child'. Our UI is supposed to be a tree. Does a tree have that structure?

lfn308:02:40

No, one of the parents doesn’t have a child. Here’s the state that’s being fed to the reconciler:

{:tasks [[:tasks/by-id 1]
                 [:tasks/by-id 2]]         
:tasks/by-id {1 {:text "This is a task"}
                             2 {:text "This is another task" :children [[:tasks/by-id 3]]}
                             3 {:text "This is a child task"}}}

lfn308:02:30

Please excuse the formatting.

cjmurphy08:02:58

I would want to see [:tasks/by-id 3] in :tasks.

cjmurphy08:02:00

I'm not sure why by the way, just all my state doesn't miss one like that.

jimmy08:02:35

@nano: I have some defonce, but changing it to def doesn't solve the problem, kinda stuck with this 😞

cjmurphy08:02:14

@lfn3: strange (from my experience) that automatic normalization created state that looks like that.

lfn309:02:21

I can get it working by modifying the example in the om.next devcards, so I’m pretty sure it’s my fault. Haven’t figured out how yet, however.

nano09:02:15

Have anyone here made a component in omnext that holds a number of input fields that should be submitted when pressing submit, and while editing the fields, their content is being bounced to a rest resource that does something with the data, and the response is presented by the component on each change.

jimmy09:02:04

@nano: I'm not sure if I understand you. But the approach I use is to use props and when I fetch data, I merge state to props ( props < source of truth ) and states is the things you can edit and diff and such.When you transact , it will merge back to props again

jimmy09:02:36

component's props

nano09:02:45

Local state?

jimmy09:02:51

component's local states (om/get-state this)

nano09:02:02

So I would have something in the component doing the while-editing rest request, rather than going via the reconciler send?

jimmy09:02:36

what do you mean while-editing rest request ?

nano09:02:39

Sending the current values to the server for a preview while editing before committing.

nano09:02:06

Committing the form.

jimmy09:02:35

so you send the values of your form while it's being changed before committing ?

danielstockton09:02:17

@nano Conceptually, how is this different to anything else? Editing the fields triggers transacts, which trigger remote mutations, which trigger reads, which trigger re-renders of your component

nano09:02:27

Yes. Say for example getting a price preview during order edit before ordering

jimmy09:02:37

ah I can see. but the workflow like @danielstockton said, it's not different. I would just do transact, if it doesn't return errors, you just update your order preview. I would name it something like order/preview mutation. When result returns you can have a merge strategy to merge to current app state.

nano09:02:02

Im not saying this is different. What I say is what I do does not work, and I ask if anyone has done something similar.

nano09:02:09

Sure, i can transact and get the relevant data in my mutate, but i cant get that data to my reconciler send function.

nano09:02:22

It just gets the query.

cjmurphy09:02:36

I haven't done anything similar, but I think using local state for the stuff that comes back from REST as the user types would make it clean.

nano09:02:16

OK, so then doing the rest request in the component rather than reconciler send.

danielstockton09:02:56

i would just make it a part of the query, but thats my personal preference

cjmurphy10:02:18

That what I was thinking yes, but never done...

danielstockton10:02:27

i store my temporary form values (before hitting send) in the app-state

jimmy10:02:43

@cjmurphy: I just saw your message about the same error as mine. Let me double check all the thing. It's annoying 😞 I was on a good track of getting things done and this component path holds me back T_T

danielstockton10:02:45

so that i maintain the ability to undo/redo and copy state from one browser to another

nano10:02:31

@danielstockton: But to make it part of the query, and thus go via reconciler :send, I would have to use queryparams for each form field?

danielstockton10:02:56

Don't think so, I give all my forms an ident that have their own component

jimmy10:02:13

@nano: what if we do something explicitly like this (om/transact this [(order/preview params) :order-page], then in the merge function, we merge the result of that mutation to the current app-state (`:order-page`). Then thing should work

nano10:02:21

I have no idea how to pass data to the reconciler send function though. It only seems to get the query.

nano10:02:51

The only way I know is via queryparams, so then I have to duplicate the state as params, or only have params, who knows.

nano10:02:56

So I would transact the form fields to the app-state, and then also update the query each time to set the new params, that can be ripped out from the query the reconciler :send function gets.

jimmy10:02:01

I dont know if I misunderstand anything but you can pass data via params in mutation ?

nano10:02:18

Sure, but how does that data end up in the reconciler :send function?

nano10:02:31

I only get component queries in :send

nano10:02:05

Which results in horrible hacks to rip out child components parameters in cases where I use that.

jimmy10:02:14

hmm, so you haven't had mutation params sent to server before ?

nano10:02:43

The only thing I can get reconciler :send function to receive is component queries. Is it possible to pass it something else?

jimmy10:02:58

reconciler sends everything you specify in query

jimmy10:02:11

in case of mutation query, it would be the params

nano10:02:53

I'll poke around and see if I can get it to do something else. Back later when I've ruled out a number of things.

jimmy10:02:36

@nano: you can try this query (om/transact [(test-mutation/overview {:field-text "something"})] to see if on the server at 'test-mutation/overview function, you can get the params.

jimmy10:02:13

@cjmurphy: I'm on my way to add empty queries for all the things ...

jimmy10:02:19

@cjmurphy: I think in my case there is something else wrong. for example when I first on landing page, clicking around button that has transact, it doesn't work ( same errors above ). But when I go to another page, then go back, now I can.

jimmy10:02:03

there must be something that was done through switching between pages, and through debug I can see that the queries for component path is now available in indexer.

cjmurphy10:02:13

@nxqd I've never done any parametrized queries or changed queries in any way yet.

jimmy10:02:48

@cjmurphy: thanks for helping though, I think I need to dig down to find the problems.

cjmurphy10:02:29

okay bonne chance

anmonteiro10:02:15

@nxqd: that might actually be a bug in Om; I'm happy to look at a minimal case

nano11:02:29

@nxqd: Alright.. got something working now, need to make my sender function handle other requests, but it's a start!

firstclassfunc16:02:25

Does anyone have any pointers on how to initialize app-state from a remote http call?

danielstockton16:02:44

firstclassfunc: om.now?

danielstockton16:02:56

initialization shouldnt be different to any other reads, just write your queries and let the reconciler do its job

danielstockton16:02:57

your app will collect all the relevant queries into a single root query and fetch everything it needs

cjmurphy16:02:26

Is there a way to stop [om.next] transacted messages going to the browser console? I only want to stop some of them actually.

anmonteiro16:02:21

@cjmurphy: look into the reconciler's :logger option

cjmurphy16:02:16

Thx, this does the trick for now:

cjmurphy16:02:22

(def my-reconciler
  (om/reconciler {:state initial-state
                  :parser my-parser
                  :logger nil}))

ericnormand18:02:23

@dnolen: well, it's nice that it renders seqs. it was a big source of bugs.

ericnormand18:02:33

when did that happen?

ericnormand18:02:37

I missed the change

dnolen18:02:51

sorry to be clear this is an Om Next thing

dnolen18:02:05

but after someone pointed out arrays and iterables were spliceable in React

ericnormand18:02:39

ok, that's weird, because we're not using om next

dnolen19:02:00

@ericnormand: hrm well we changed it in the alphas

dnolen19:02:13

so in theory it will be work for both om.prev & next

grzm19:02:05

sometimes I see queries that are quoted (preceded with a ') and sometimes not. It looks like they're quoted if there's a list (as opposed to a vector or a map) somewhere in the query, but sometimes I see queries without lists that are quoted. What's the reasoning of when to quote and when not to quote?

jlongster20:02:01

@grzm: if you use any syntax other than literal objects you need to quote

jlongster20:02:22

either you need to splice in a variable or some other syntax that is invalid Clojure

grzm20:02:48

@jlongster: gotcha. that makes sense. So I was on the right track

hueyp20:02:00

so is it reasonable to think of links/idents, how they appear in a query vs how they are stored as two separate ideas? if you have a parser, don’t use the default db format, how the state of an ident looks is totally up to you?

hueyp20:02:59

e.g. if you wanted to use datascript, queries with links are valid, and it would be up to your parser to sort of ‘pull them out’ and work with appropriately

jlongster20:02:18

@hueyp: I'd say that's right. they only have meaning to db->tree and tree->db. if you use something like datascript you'll have to implement your own version of those, which implements the same semantics of links & idents (if you even want to use the same syntax)

hueyp20:02:22

thanks, I’ve been slowly coming to the conclusion that db->tree is convenience, not required … which I mean, is right in that devcard tutorial … just takes awhile to sink in simple_smile

hueyp20:02:50

like the ‘default database’ format is there to start, but it is not ‘bad’ if you don’t use it

jlongster20:02:44

definitely not, I started with the wiki tutorials which don't even use it, which I think is a nice way to start. eventually condensed my read function to just use it, but it's fine if you don't (or even just use it for parts of the tree)

hueyp21:02:58

is there any built in function to ‘flatten’ a query? e.g. [{:item [:id :title [:current-user _]]}] into [{:item [:id :title]} [:current-user _]]

teslanick22:02:46

I have a collection of items where each item references a value in another collection (SQL equivalent of inner join), but the keys don't line up. I haven't seen a clear answer to whether I can declaratively relate the two sets of items together.

teslanick23:02:56

e.g. it seems like I should be able to use an ident like the "thinking with links" guide, but the unique ID for the ident is going to be dynamic for each member of the collection, and don't know how to do that.

ethangracer23:02:07

Anyone know if it’s possible to access Object methods outside of the defui? For example:

(defui List
   …
   Object
   (helper-method [this]
       ;; do stuff)
   (render [this] … (.helper-method this) …))
If I want to write a test for helper-method, is there a way to generate a React element instance that I can use to call the function? Tried playing around with om/factory but couldn’t find a way to call the instance method from the return value.

hueyp23:02:12

@ethangracer: given the List or something else?

hueyp23:02:22

given the List you can do (.keys js/Object (.-prototype List)) but there might be a way smarter / clojurescript way to do it

ethangracer23:02:41

well that gets me there! I was hoping for something a little bit cleaner but so it goes simple_smile Thanks

hueyp23:02:03

there might be … honestly I’m a bit hazy on all the right / wrong ways to get an objects properties simple_smile