Fork me on GitHub
#om
<
2015-10-16
>
mfikes03:10:37

Starting to feel the need to try out Om Next with React Native. simple_smile I’m especially interested in what it might mean for queries in the mobile context (too many hand-crafted / optimized REST-based data fetches in my apps currently).

tyler03:10:44

@mfikes I support that effort. I’ve given it a couple of attempts but I can’t figure out how to mount the root component.

mfikes03:10:20

@tyler Have you tried Om (Now) with React Native?

tyler03:10:52

I have dabbled but I don’t have enough experience with react native to know my way around

mfikes03:10:05

I used (om/root widget app-state {:target 1}) in http://cljsrn.org/ambly.html

mfikes03:10:29

(That {:target 1} was a pain to discover.)

tyler03:10:33

I saw that and tried with om.next but I wasn’t able to get anything to render

tyler03:10:42

I was going to ask, where does that come from?

mfikes03:10:08

Ahh… OK. Maybe something is different with Om Next.

tyler03:10:48

I tried with a very early version… also I haven’t dug into it so its very possible I was neglecting something trivial

mfikes03:10:58

I think I got {:target 1} from reading React Native JavaScript source, trying to piece together something that would work.

tyler03:10:03

I might take another stab at it over the weekend. I’ll let you know if I have any luck the second time around

mfikes03:10:33

Reagent uses something similar: (r/render [root] 1)

mfikes03:10:13

Cool, get out your machete and hack away

zentrope03:10:25

Is it possible to use om (or any cljs react framework) with react-native just as-is? In other words, compiling straight to (say) index.js?

zentrope03:10:38

Esp. if you don't care about repls and so on?

tyler03:10:06

I believe it was the target bit that was tripping me up. Also the version of om.next I was using didn’t allow you to just implement a render fn (without a query) so that was tripping me up as well trying to get a simple component on the screen

a.espolov03:10:07

Guys I can not understood how to defined the methods react with om.next

mfikes03:10:39

@zentrope: This project appears to do something close to that, with Reagent: https://github.com/chendesheng/ReagentNativeDemo

tyler03:10:42

@zentrope yes. In theory, the repl is the trickiest bit to my knowledge.

a.espolov03:10:49

or just a method render is available at the moment?

zentrope03:10:22

mfikes: It seems like a while ago you were saying no, based on the need for "require" (if I remember correctly).

mfikes03:10:29

I ended up taking that project and making it work with Ambly. See http://blog.fikesfarm.com/posts/2015-07-20-reagent-react-native.html

mfikes03:10:20

@zentrope: Oh… right, you said index.js above...

zentrope03:10:54

mfikes: What I'm really interested in is not having to do anything extra with the ObjC / Xcode part of the project.

mfikes03:10:06

@zentrope: The problem is the model with React Native’s Packager, etc.

zentrope03:10:17

mfikes: Using a pure js index.js (or whatever) to start things up is good enough.

mfikes03:10:40

We just need to convince Facebook to adopt ClojureScript.

zentrope03:10:13

What do you mean by “model with React Native’s Packager”?

zentrope03:10:28

Looking at the ReagentNativeDemo, it seems like he just runs lein to build to main.js, then runs and deploys ReactNative as normal.

zentrope03:10:13

In other words, the only difference is having to run that extra build step beyond what you’d normally do for a pure ReactNative project.

adamfrey04:10:59

reminder to everyone that if you are using the latest Om releases and you have devcards in your deps, you are going to want to add an exclusion for the older transitive dependency on React: [devcards “0.2.0-4" :exclusions [cljsjs/react]]

steveb8n04:10:21

@dnolen: I’ve just completed the tutorials (in Cursive, that screenshot was gold!) and it all worked great. I hit one issue with needing to be in the correct namespace but it was easy to suss out. That might catch cljs noobs though. If anyone else had a similar issue, maybe mention it here so we can see a pattern. Thanks everyone for the feedback, it helped me getting through as well.

thomasdeutsch07:10:09

@steveb8n: can you please repost the screenshot from davids repl config?

dvcrn09:10:18

hey guys!

dvcrn09:10:43

I'm currently knocking my head against om.next and don't understand a few things. Hope someone here can give me the hint I need

dvcrn09:10:29

I'll just dump my question in here. If someone knows what I'm doing wrong, please ping me.

dvcrn09:10:16

Sooo, I have a Component called CodemirrorComponent. It requests for :codemirror from my state.

(defui CodemirrorComponent
  static om/IQuery
  (query [this]
         '[:codemirror])
...
Next up, I have my RootComponent that tries to mount codemirror. Now the way I understand the query system is, that rootcomponent queries my codemirrorcomponent for what data is requesting, composes a query and retrieves data from my reader. I read through the om.next wiki and created something like that:
(defui RootComponent
  static om/IQuery
  (query [this]
         (let [subquery (om/get-query CodemirrorComponent)]
           `[{:app ~subquery}]))
The state atom looks like this:
(defonce app-state (atom {:app {:window {:w 0 :h 0} :codemirror nil}}))
None of my component requests :window (yet), however when I check what's inside (om/props this) inside render, I get the entirety of :app, including :window. Is that how it is supposed to work or did I mess up somewhere in between?

sander09:10:36

@dvcrn: think that depends on your reader method

dvcrn09:10:35

I have a super simple reader right now:

(defmulti read om/dispatch)
(defmethod read :app
  [{:keys [state] :as env} key params]
  (println "reading")
  (println key)
  (println params)
  {:value (@state key)})
though there are no parameters (like the subquery) in there which I could use to filter the state further

sander09:10:50

@dvcrn: what's the value of params?

dvcrn09:10:06

nil with the code above

thomasdeutsch09:10:44

i think that the CodemirrorComponent is expecting a reader named :codemirror or a :default reader

dvcrn09:10:11

let me try that

dvcrn09:10:06

though :codemirror is available as subquery inside the RootComponent. I think my problem is also that I don't quite understand what [{:app ~subquery}]` exactly is doing

thomasdeutsch09:10:58

short: `[...] is a template and ~ will resolve a symbol inside that template. See this example: https://clojuredocs.org/clojure.core/unquote look for "unquote macro" for more infos

sander09:10:32

so your query will become [{:app [:codemirror]}]

dvcrn09:10:50

that's what I suspected. Though how can I access // filter on that inside my reader and not just give the entire content of :app?

dvcrn10:10:47

Ok I found a "workaround" if you can call it like that. I flattened out the data and merged the subqueries into 1 flat vector app-state:

(defonce app-state (atom {:codemirror "codemirror" :window {:w 0 :h 0} :foo "bar"}))
The RootComponent is now collecting the subqueries, merges them together and passes the entire collected state to the child
(defui RootComponent
  static om/IQuery
  (query [this]
         (let [subquery (om/get-query CodemirrorComponent)]
           (into [] (concat subquery [:foo]))))
  Object
  (render [this]
          (codemirror (om/props this))))

dvcrn10:10:23

ah crap, this results in No queries exist for component path for some reason. Well it's getting late, I'll let this rest and look at it with new eyes tomorrow

thomasdeutsch11:10:18

i could need some help in solving a simple om.next/datascript task. rendering one of two components - dependent on what component is selected. I created a simple gist. could need some help to solve this the om.next way. https://gist.github.com/ThomasDeutsch/f8c056b498efd22c5e0c

dnolen11:10:06

@thomasdeutsch: I haven’t had time to document it in a tutorial yet but read about subquery

dnolen11:10:56

it’s a helper for dynamic query selection at runtime

dnolen11:10:35

in your case you might not actually use it, but look at how it works.

thheller11:10:13

@thomasdeutsch: I ran pretty much into the same issue. any progress on your end? simple_smile

thomasdeutsch12:10:21

working on it - looking for a nice idieomatic (om.next) way to solve this. The set-query! function will not be right at this point. I think that @dnolen quessed it right, and subquery is just what i need. https://github.com/omcljs/om/blob/48489aac9c1f00bbaaeb4deb0cb0e2a8a25890c3/src/main/om/next.cljs#L459 Damn, i could need a very small example.

thheller12:10:25

from what I gather from subquery it doesn't work in my case cause the ref not being a single element but a collection

thheller12:10:37

but yeah an example would probably clear that up

thheller12:10:15

problem seems to be the polymorphic nature of the data

thomasdeutsch12:10:27

in my gist, i could read the whole entity with this query:

'[{:selected-menu [{:selected [*]}]}]
and then decide what to render based on the data. Is that the om.next way to solve this? i do not know 😉

thheller12:10:29

or just me not understanding it

mfikes12:10:30

@zentrope: In chendesheng’s ReagentNativeDemo, the React Native Packager is packaging the concatenated (`:whitespace`) output of the ClojureScript compiler. With that model, development involves

1. Change ClojureScript source
2. Compile ClojureScript source (perhaps via auto)
3. Hit Cmd-R in the simulator
4. The app in the simulator talks to the packager and gets a new copy of the bundle (React Native JavaScript along with the embedded ClojureScript compiler output)
5. This stuff is loaded into JavaScriptCore
6. UI is re-rendered
7. Go to 1
That’s what I mean by “model that involves the React Native Packager”. This approach has pros and cons of course. Some of my thoughts on this are at https://github.com/reagent-project/reagent/issues/119#issuecomment-109643876

donmullen13:10:58

@mfikes: Is there a path where we could hook into the app running in the simulator so that finishing the cljs compile will trigger #4 automatically?

mfikes13:10:07

@donmullen: I bet React Native's “Live Reload” would work.

mfikes13:10:38

@maria: With respect to directly consuming React Native libraries (without using the React Native Packager), do you recall ever seeing a construct that categorically prevents consumption for now—my guess would be the use of Facebook's proprietary module format with @providesModule—or is it still an open question and an area of research in your opinion?

mfikes13:10:23

I apologize that this is probably not the right channel for this message.

dnolen13:10:58

k sorted through Om Next advanced compilation issues, working on a Dynamic Queries tutorial now

dvcrn13:10:23

is alpha3 currently working? I thought it was my code but even the tutorial throws errors

dnolen13:10:20

@dvcrn: a few have gone through it now w/o reporting any problems

dnolen13:10:41

it’s important to follow the instructions exactly, do not bring in any 3rd party things or change any of the configuration … at all

dvcrn13:10:57

hmm... odd. Let me try again

dnolen13:10:12

make sure you’ve cleaned your build etc.

thomasdeutsch14:10:37

@dvcrn: if you use figwheel, try to run

`(reset-autobuild)
in the figwheel prompt

dnolen14:10:28

@thomasdeutsch: so looking at your problem I’m not sure why you are having trouble

dnolen14:10:40

people seem confused about what the “query” is

dnolen14:10:10

in your parser you can run the query to get the right menu

dnolen14:10:59

@thomasdeutsch: having two menu components seems gratuitous

dnolen14:10:22

I’m not going to write a tutorial on this particular example as this seems like a UI modeling issue

dnolen14:10:02

@thheller: while I’m not going to look at your code in it’s current state, it’s too long. I’m more than happy to actually talk through the trouble you are having.

dnolen14:10:33

it does not seem related to @thomasdeutsch’s issue

thheller14:10:44

@dnolen sure I'd love that. honestly do not know how to make the code any shorter

dnolen14:10:01

right but at this point I don’t even want or need to look at code

dnolen14:10:05

the problem should be describable

dvcrn14:10:47

okay, I cleaned everything and tried again. The first few examples are working but as soon as I add the reconciler with mutate and read, it gives me Cannot read property 'render' of undefined. Problem appears at this step - https://github.com/omcljs/om/wiki/Quick-Start-%28om.next%29#naive-design. I tried rolling back to the alpha1 snapshot that I used before and it seems to be gone.

thheller14:10:37

I have a CMS with several object types. I get a list of "most recently changed objects" from the server. I want to render this list with each item being rendered by its corresponding om.next component

thheller14:10:20

the problem I have is that the component is chosen by its :type property

thheller14:10:30

which happens in (render ...)

thheller14:10:46

I cannot create a Query for it

dnolen14:10:11

right so this is the “dashboard” problem

dnolen14:10:23

you have N types of components and you don’t know what you’re going to display.

dnolen14:10:28

nor what properties they will need.

thheller14:10:53

well, the display works fine so far

thheller14:10:57

its the mutate that fails

thheller14:10:05

items in the list may create "shortcut" actions (ie. a button to click)

thheller14:10:09

that action should modify stuff

dnolen14:10:27

right but the mutation part isn’t the problem.

dnolen14:10:33

let’s avoid talking about that, not relevant.

dnolen14:10:41

the problem is only what I’ve said above.

dnolen14:10:41

so in order for Om Next to do its thing it needs to understand the data about to presented so it can normalize it.

dnolen14:10:03

this is related to updating, but also matching “identical” components

dnolen14:10:25

but that’s the fundamental issue, we can’t normalize the data based on upfront information.

dnolen14:10:51

well also that there’s no query for the component ...

thheller14:10:59

I sort of cheated and created a normalized dataset to begin testing things

thheller14:10:10

but yeah expressing the query is the problem I have

dnolen14:10:18

OK will have to think about this for a bit

dnolen14:10:05

Yeah you can't express the query up front in this case

dnolen14:10:23

but it's something we should be able to handle

dnolen14:10:34

heterogenous dynamic data will not be uncommon

thheller14:10:54

ok cool. thanks .. was beginning to think I got something fundamentally wrong

dvcrn14:10:10

If anyone is interested in my problem, I pushed the project in it's current state to github - https://github.com/dvcrn/dmedit/tree/develop. The code in question -- basically the tutorial -- is here https://github.com/dvcrn/dmedit/blob/develop/src_front/dmedit_om/core.cljs

bbss14:10:15

dvcrn: I ran into the same problem

dvcrn14:10:23

oh you did? how did you solve it?

bbss14:10:32

Do you use cursive?

dvcrn14:10:49

I'm trying it right now but I used emacs / cider before

bbss14:10:06

when I launched the figwheel script via terminal the right react got installed but when I ran it through cursive somehow the old react was on the classpath (you can check that on the first line when launching the repl via cursive.

dvcrn14:10:38

hmm no I don't launch it through my editor. I use the embedded figwheel nrepl and point the editor to that

bbss14:10:22

I removed the dependency from my project structure view and ran the action "synchronize leinigen dependecies" which used to be default when launching but now is not available.

bbss14:10:35

Then it installed the right version.

dvcrn14:10:34

now that you say it, the react that's in the dom is 0.13.3 and not 0.14

dvcrn14:10:40

didn't notice that

bbss14:10:55

lein clean
lein run -m clojure.main script/repl.clj
installs the right react for you? You can just paste that one in, it shouldn't overwrite

bbss14:10:59

file > project structure > modules

bbss14:10:12

is there a dependency on react for you?

dvcrn14:10:18

let me check

dvcrn14:10:38

there is and it's pointing to 0.14

bbss14:10:25

Okay, for me there was an old one. Removing it solved my issue.

dvcrn14:10:29

mhm I literally just installed cursive for the first time

bbss14:10:08

It's great! Sending code to repl from your cursor is a powerful thing simple_smile

dvcrn14:10:23

emacs can do that too 😛

bbss14:10:21

Yeah I figured it could simple_smile but cursive + jetbrains editors have enough to satisfy my needs.

dvcrn14:10:01

I'm a vim dude and need good bindings and the ideavim plugin is not that good (yet).

dvcrn14:10:23

I deleted my compiled folder, cleaned the build but after running figwheel it is still react 0.13.3

dvcrn14:10:39

react-dom is 0.14 though

bbss14:10:49

can you do lein deps :tree ?

bbss14:10:06

there might be sablono that is still depending on the old.

bbss14:10:14

adding exclusions* will break sablono btw

dvcrn14:10:20

ohh I use sablano! that could be it

dvcrn14:10:21

let me check

dvcrn14:10:35

Possibly confusing dependencies found:
[sablono "0.3.6"] -> [cljsjs/react "0.13.3-0"]
 overrides
[org.omcljs/om "1.0.0-alpha3"] -> [cljsjs/react-dom "0.14.0-0"] -> [cljsjs/react "0.14.0-0"]
 and
[org.omcljs/om "1.0.0-alpha3"] -> [cljsjs/react "0.14.0-0"]
roaaar...

dvcrn14:10:39

yup that was it. The problem is gone

dvcrn14:10:07

thanks a lot @bbss! I spent hours scratching my head on this. Never suspected the react version to be the culprit

bbss14:10:00

Hahah, yeah me too! I had some weird issues that I still don't get. But I am pretty new to clojure so.

dvcrn14:10:22

yeah same here

bbss14:10:49

But you could have found out that it was react by looking at the stacktrace in the devtools.

dvcrn14:10:16

I knew that it was react but not more 😛

thomasdeutsch15:10:46

@dnolen: i think my problem is the same as @thheller described. I can not tell what sub-component will render, only after i got the data i am able to determine the right sub-component. i am not able to build a query for it upfront. Maybe i should just wait for the dynamic queries tutorial.

dnolen15:10:04

@thheller: OK I have a nice solution to your problem simple_smile It’s a good case for the “Dynamic Queries” tutorial. And when thinking about the server side bits made me realize that code sharing between Clojure(Script) is just freaking awesome.

dnolen15:10:26

@thomasdeutsch: OK, it just that the UI components involved are not a good way to talk about the problem.

dnolen15:10:31

the “Dashboard” is

thheller15:10:37

@dnolen cool, can't wait

thomasdeutsch15:10:21

me, too. thanks!

dvcrn15:10:24

what exactly is the difference between

(defui RootComponent
  static om/IQuery
  (query [this]
         (let [subquery (om/get-query SomeOtherComponent)]
           '[(:app {:query ~subquery})] ))
(used inside https://github.com/omcljs/om/wiki/Quick-Start-%28om.next%29#changing-queries-over-time to filter a query) and
(defui RootComponent
  static om/IQuery
  (query [this]
         (let [subquery (om/get-query SomeOtherComponent)]
           '[{:app ~subquery}] ))
like written in here https://github.com/omcljs/om/wiki/Components%2C-Identity-%26-Normalization#adding-reads The first one passes the parameters to the reader, but what about the second one? I couldn't follow where the subquery is being used or what happens to it

anmonteiro15:10:55

the 2nd one declares which subkeys of :app you want

dvcrn15:10:07

do I need a specific reader to make use of that? Right now it just returns the entire :app object even though the subquery specifies keys, that's why the question

anmonteiro15:10:42

yep, but I believe it'll not return every key in the :app object once it connects to e.g. datomic

dvcrn15:10:04

ohh, I'll steal that

bbss15:10:27

Oh right, I wanted to do that too! Thanks @anmonteiro

anmonteiro15:10:46

go ahead, that's why I uploaded it

dvcrn15:10:03

so I guess if I only work with local state it is smarter to use prop + params and write my own reader that filters the state?

anmonteiro15:10:36

I think if you only work with local state you don't need queries (?)

anmonteiro15:10:54

you meant local as opposed to remote

anmonteiro15:10:57

i get it now

dvcrn15:10:16

I don't want to dump the entire global atom into every component

anmonteiro15:10:56

prop + params is intended to be used with IQueryParams, you get that ye?

dvcrn15:10:38

yup, kind of

dvcrn15:10:00

hmm. what would be the optimal way to get something like the cursors from om legacy back?

dvcrn15:10:11

where each component only uses a partial of the app-state

anmonteiro15:10:34

i think queries will do that

dnolen15:10:55

but also not something I care about at all

anmonteiro15:10:32

@dvcrn: like, if you only query :x and :y, the component's props will only have :x and :y I suppose

anmonteiro15:10:42

@dnolen: please correct me on this one

dnolen15:10:12

@anmonteiro: right, but the root will get the world and pass whatever pieces it wants down

dnolen15:10:26

so the parent is in control, however it does have all the pieces all children will need

dnolen15:10:44

if you muck that stuff that’s you’re own fault, not putting up guard rails for this

dnolen15:10:45

waste of time

dnolen15:10:24

also the root doesn’t get the actual world

dnolen15:10:31

now that we live in a forced normalized reality

dnolen15:10:39

it’s just a view

dvcrn15:10:04

hmm I see

gardnervickers15:10:21

ahhhh that makes sense ok

anmonteiro15:10:47

@bbss: that 'join + params' contains a typo (that were in the slides), it should be [({:some/key [:sub/key]} {:arg :foo})]

anmonteiro15:10:01

also curly braces in join + selector

bbss15:10:57

corrected?

anmonteiro15:10:45

nope, meant like this: [{:some/key [:sub/key]}] ;;join + selector

dvcrn16:10:22

so given that, how would my rootview/component actually orchestrate all the queries that the childs want without dumping the same piece of state into all components? Say my compA defines [:foo :bar], compB wants [:baz :moo]. My rootview collects it and then? Do I just construct a big map and pass it to my reader that then knows how to pick that from the state atom?

anmonteiro16:10:04

@dnolen: I was trying to make a "reusable component" that could receive other components (w/ arbitrary data) but I don't know what to query for; is this the 'Dashboard' issue you were talking about above? that reading the upcoming dynamic queries tutorial will give me a notion on how to handle it?

dnolen16:10:51

@anmonteiro: it’s important not over think things

dnolen16:10:02

if you have a truly pure component - it’s doesn’t need queries at all

dnolen16:10:18

@anmonteiro: the tutorial may cover the actual problem you are trying to solve, you’ll have to read it and see for yourself.

dvcrn16:10:19

So I should not think of queries as a "I'm going to filter the piece of state that my parent gave me as parameter"?

anmonteiro16:10:31

so this error message should be for something completely different? "{:message "No queries exist for component path (deathrow.offender/Offender deathrow.common/GenericPanel)", :data {:type :om.next/no-queries}}"

dnolen16:10:59

@dvcrn: the parent filters the state for the component

dnolen16:10:25

children never receive more than was handed down by a parent as requested by the child query

dnolen16:10:14

@anmonteiro: I have no idea what you are trying to do.

dnolen16:10:31

@anmonteiro: wait for the dynamic queries post and see if it solves your problem.

dnolen16:10:46

but when someone says “resusable” component

dnolen16:10:52

that means no queries

dnolen16:10:15

queries are for application stuff, not reusable components

dnolen16:10:43

and by “resusable” I mean I can drop it into any project

anmonteiro16:10:48

makes total sense

dnolen16:10:56

not “reusable” between my company's projects where our DB looks the same

dnolen16:10:06

queries are OK in this case

dvcrn16:10:22

though isn't the parent using the query information to provide the child with the information in the exact same format it needs to operate?

anmonteiro16:10:54

btw is the :send option in the reconciler something to use or is it deprecated since it doesn't appear in the documentation (yet?)

dnolen16:10:28

@anmonteiro: something to use, haven’t gotten around to describing that yet

dnolen16:10:32

that’s for remote sync

dnolen16:10:53

works great! I have it hooked it up to datomic in the om-next-demo on GitHub

anmonteiro16:10:03

yep that's where I saw it!

anmonteiro16:10:46

but that got me into another trouble though; 2 actuallly. I'll try to describe them succintly

anmonteiro16:10:31

1. somehow I got the impression that it expects a datomic-like response; so if you query for :foo datomic will return {:foo {..other stuff..}}; but if we're communicating say with a JSON api that'll return a response object then ALL keys in the object will be merged in to our app-state; is there a way to define a custom merge that "assocs" the response into the key we queried for?

bbss16:10:56

Isn't that demonstrated in the identity tutorial, where one of the persons has info on age but it's not included after normalisation?

anmonteiro16:10:48

this is something different (and related to remote responses, I'd say): say you query for :foo which will be a map e.g. {:a 1 :b 2} ; my problem is that instead of getting {:foo {:a 1 :b 2} in the app-state, I'll get {:foo nil :a 1 :b 2} (if I had declared :footo be nil previously; otherwise I'll just get {:a 1 :b 2})

anmonteiro16:10:22

as in, the response object isn't merged into the app-state atom, its contents are

anmonteiro16:10:47

my current workaround is to return a map with the queried key as key and the response object as its value; then everything works great

dnolen16:10:10

@anmonteiro: that’s not how it works

dnolen16:10:29

if you’re going to talk to a remote service that service will return the same shape of thing that a parser does

dnolen16:10:41

it must be normalized, and then we merge with merge-with

dnolen16:10:13

you can customize this look at reconciler, but it’s not something I recommend yet

anmonteiro16:10:52

@dnolen: OK that makes sense, and I can live with it; then to my 2nd problem: how to handle an error? what should I pass to the callback?

dnolen16:10:15

@anmonteiro: error handling beyond the simple stuff that is in place needs to be sorted out

anmonteiro16:10:21

if I pass e.g. {:queried-key :not-found} merge-with will throw

bjr16:10:30

@dvcrn: you can snag a selector specified in a query via the env param. so if you’re going from ParentComponent with query [{:key ~subquery}], the read handler for :key will have that subquery at (get env :selector)

dnolen16:10:11

what we end up with largely depend on what people want. Based on the various demands I’ll pick something that works for enough cases.

dnolen16:10:25

Absolutely uninterested in making everyone happy with regards to the error handling story.

dnolen16:10:31

Just need something that people can live with.

bjr16:10:35

@dvcrn: not sure if that’s why right way to do it, but it’s there

dnolen16:10:26

@anmonteiro: also been looking closely at Relay & Falcor for ideas

anmonteiro16:10:34

@dnolen: totally understand; just reporting stuff that I've encountered hoping that it helps shape things up

dnolen16:10:36

we may very well just pick something that’s already been done

bbss16:10:58

I am hoping there will be a story for syncing automatically, say if connections fail or when you move from offline to online simple_smile

anmonteiro16:10:47

@bbss: that sounds like an extension to me, like https://github.com/swannodette/om-sync was to Om Legacy

dvcrn16:10:29

@bjr I'm just trying to understand the ideal workflow. Say I have a root component that mounts 2 other components. - root wants the window size so it asks for [:window], right? - componentA wants :window as well and :foot - componentB wants :html and :bar All this information is locally and not retrieved from a server (yet) Do I now: - Just retrieve all that stuff in root and pass it to the components as parameters or - Let the childs declare queries and read them inside root. If 2nd option, then how do I orchestrate this? Do I use '[(:app {:query ~subquery})] to pass that query to my reader which then filters for me based on the parameter? Or do I use '[{:app ~subquery}] which I still don't quite understand as it always gives me the entire :app

bbss16:10:53

@anmonteiro: right like that 😄

bjr16:10:01

@dvcrn: in the latter example of the 2nd option, you’d have to implement the reader to use the subquery selector

dnolen16:10:17

@bbss: no story for offline other than you can figure that out on your own

dnolen16:10:31

as in Om doesn’t need to do anything about that, it’s user solveable

bjr16:10:41

I think they’re the same, just passing the selector in a form the parser recognizes as the selector vs as a param and interpreting it yourself

anmonteiro16:10:45

@dvcrn seems like you'd want something like [(om/get-query componentA) (om/get-query componentB)] and so on

bbss16:10:11

Yeah I figured this approach would allow for easy solving of these problems simple_smile

anmonteiro16:10:54

@dvcrn: you can always query more than one thing inside the vector

bbss16:10:00

What's the best place to learn about pull syntax: http://docs.datomic.com/pull.html ?

anmonteiro16:10:41

@bbss: that's what I read

dvcrn16:10:37

@anmonteiro: ok that makes sense. Now my RootView has the subqueries. What I did before is, I merged them into 1 big vector and returned that as IQuery from my rootview. The problem is that with this approach I will receive 1 big map back that matches my vector. Can I somehow avoid that componentA gets :html or componentB gets :window? Since I query all this stuff at the same time I can't really differentiate which component queried what Could I do something like (:app {:componentA ~a-subquery :componentB ~b-subquery}) and then use my reader to map it into different keys? Then retrieve these keys inside render and pass only :componentA to component A and so on or is that the wrong approach?

dvcrn16:10:57

sorry it's 2am here. I should probably go to sleep and stop spamming around here 😇

anmonteiro16:10:15

@dvcrn: "retrieve these keys inside render and pass only :componentA to component A and so on " --> I think that's the way to do it

anmonteiro16:10:53

so something like (select-keys (om/props this) (om/get-query ComponentA)) etc

dvcrn16:10:19

hmm okay I will try that tomorrow

dvcrn16:10:29

My first thought was that this is not "om-next-ey" enough

anmonteiro16:10:44

mine too, but that's what every tutorial does

anmonteiro16:10:53

so I assume it's the way to go about it

dvcrn16:10:15

all right simple_smile thanks a lot for bearing with me so long lol

anmonteiro16:10:34

np we're all trying to grok something very new to all of us 😛

thomasdeutsch16:10:49

i hope that more people will be looking into datalog. datascript/datomic is a really fun environment to code with.

anmonteiro16:10:46

@dnolen: I've got a followup to #417 do you prefer a new issue or should I just post a gist here?

dnolen17:10:27

@anmonteiro: before I look at a gist just explain the perceived problem

anmonteiro17:10:44

the problem is the same, the query will throw an odd error

anmonteiro17:10:51

now after proper normalization

anmonteiro17:10:05

without params, it works as expected, adding params breaks

anmonteiro17:10:39

I've omitted any Object methods in the gist because this happens before render: https://gist.github.com/anmonteiro/1551f72d8df9cc98d836

dnolen17:10:14

@anmonteiro: add that complete example with the error to a GH issue, will have to look at it later

dnolen17:10:51

@anmonteiro: just write "problematic query" for title, and include a description of the steps, thanks

ericlavigne18:10:43

What's the expected way to reference components from a REPL? Found class->any but it expects a reconciler as its first argument. Am still playing with fairly simple components with no global state, so needing to configure a reconciler seems like a big dependency before being able to use the REPL. My first attempt at this succeeded in referencing a component, but (because it's my first time configuring a reconciler) had the side effect that components no longer re-render when their state changes.

dnolen18:10:26

@ericlavigne: there is no other way, you need to supply a reconciler

dnolen18:10:35

given auto-completion this is not really a big deal

dnolen18:10:49

even more important, it’s not like you even have this feature in regular React 😛

ericlavigne18:10:47

React JS programmers can't refer to their components in the REPL? That's crazy! 😮

ericlavigne18:10:43

Okay, so reconciler absolutely necessary. Guess I need to figure out what went wrong that this reconciler broke my application.

ericlavigne18:10:49

Already had component called ExampleSelector created with defui. Old code to use it was: (def example-selector (om/factory ExampleSelector)) (js/React.render (example-selector) (gdom/getElement "app")) New code using reconciler was: (def app-state (atom {})) (def reconciler (om/reconciler {:state app-state})) (om/add-root! reconciler ExampleSelector (gdom/getElement "app")) After that change, I could reference components from REPL, but changes to ExampleSelector's internal state no longer resulted in re-render. (I could verify the state changes because I could now see in REPL.) What did I do wrong with the new code? Do I need to explicitly create reader/parser configuration for what Om was previously doing automatically?

bjr18:10:59

I think you need to supply a parser

dnolen18:10:13

@bjr @ericlavigne that’s actually not a strict requirement, the idea is that you could write an Om application without those bits

dnolen18:10:27

but it’s not a priority for me at the moment

dnolen18:10:37

I’ll circle back when the hard stuff gets finished

bjr18:10:41

@dnolen: parent components would pass props directly to children components?

dnolen18:10:36

@bjr probably I’m not going to think about this now

dnolen18:10:37

cache is full

gardnervickers19:10:27

I am trying to pass an Om component to a React component as props, is there any way to parameterize the component before I pass it? Tried using an om/factory and passing props before passing to the React component, but React complains about getting an Object instead of a class/function.

ericlavigne19:10:36

Found a workaround until I can get reconciler working correctly: specifically create my own indices for the components that I'll be inspecting from REPL. top-level: (def example-selector-index (atom nil)) first line of ExampleSelector render: (reset! example-selector-index this) So now in REPL I can use: (om/get-state @example-selector-index)

dnolen19:10:57

@ericlavigne: I recommend going through all the tutorials I wrote to avoid having to do that simple_smile

dnolen19:10:08

if you want to change something they are simple enough to serve as templates

ericlavigne19:10:45

@dnolen: By "all" you mean these six Om Next tutorials? https://github.com/omcljs/om/wiki#om-next I am slowly working my way through the "Quick Start" at the moment, and writing small example components as I go. There's a lot to absorb, and I thought REPL would help with the learning process. Reconcilers are complicated and much further into the tutorial. Tried skipping ahead and copy/pasting but the resulting reconciler breaks my other code. Several of my components use "getInitialState" which isn't mentioned in the tutorial, so probably the tutorial reconciler just doesn't work with stateful components.

dnolen19:10:00

@ericlavigne: you should go through the first 2

dnolen19:10:21

@ericlavigne: read everything and go in order is my advice

ericlavigne19:10:51

Okay, will do.

lobo21:10:07

i'm trying the first om-next tutorial and figwheel-sidecar is not reloading the browser (chrome 46.x). i upgraded sidecar to 0.4.1

lobo21:10:26

any ideas why? i've had it working with previous incarnations of figwheel (w/o sidecar)

lobo21:10:31

no errors

lobo21:10:50

(it does not rebuild either, bit when i force a rebuild, the browser still does not reload)

dnolen21:10:14

@lobo: does it work in another browser?

lobo21:10:52

actually i did not test. hang on. let me try using FF

lobo21:10:56

no, it did not

lobo21:10:00

there are at least 2 issues

lobo21:10:04

figwheel is not rebuilding

lobo21:10:27

and when i force a rebuild (reset-autobuild), it does not reload the browser

lobo21:10:42

but it is connected to the browser

lobo21:10:54

since an js/alert box appears if i invoke from the figwheel repl

dnolen21:10:00

@lobo so this is not really a Om issue if you are really following the instructions. I would ask in #C03S1L9DN bhauman

lobo21:10:48

ok will do, i was checking if it was a known issue

steve21:10:10

Howdy... looking for some newbie help

steve21:10:24

My app state looks like this: (defonce app-state (atom {:counter 0 :list [1 2 3 4 5]}))

steve21:10:44

and I have a om/IWillMount (will-mount [_] (js/setInterval (fn [] (do

steve21:10:36

on every Interval I'd like to increment the counter... and increment the number in the list by one corresponding to the position indicated by (mod counter (count (list)))

steve21:10:17

I have this for the counter

steve21:10:18

(om/transact! data :counter #(do (println (string/join " " ["js/setInterval ctr:" %])) (+ (int %) 1)) :update)

steve21:10:44

and would like to do something like this (om/transact! data :list #(....

steve21:10:01

for the list but how do I access the new counter value in that anonymous function?

steve21:10:25

Thanks ahead of time for any help

dnolen21:10:21

@steve please use a pasting service, hard to tell what’s going on otherwise

steveb8n21:10:21

@dnolen: any thoughts on how to make an app “reloadable” according to the figwheel definition? e.g. the identity tutorial resets state on every save. I could try applying the latests state snapshot on ns load but wonder if there is a best practice for this?

dnolen21:10:34

@steveb8n: there are some hooks for this but it’s low priority for me at the moment to explain this

dnolen21:10:41

maybe in a couple of weeks

dnolen21:10:45

when I have time for “fun” stuff

noonian21:10:47

@steveb8n: I think it should work fine if you just use defonce for the app-state atom and the reconciler

dnolen21:10:01

@noonian: there are other things to think about

steveb8n21:10:28

@dnolen: fair enough. I’m looking forward to the remote stuff as well so I’m happy that it is a priority

dnolen21:10:32

reconciler, ^:once on defui, normalization yada yada

dnolen21:10:43

anyways I’ll get to it when I have time

dnolen21:10:01

otherwise you’ll have to sort it out by understanding how Om Next works

dnolen21:10:11

which I don’t exactly discourage by any means

dnolen21:10:17

the architecture is unlikely to change

noonian21:10:38

yeah with reloading I think you have to be willing to dig into it

dnolen21:10:02

fear not Figwheel & DevCards are on my mind

dnolen21:10:08

Om Next will be awesome with them

dnolen21:10:17

but lets fix the basics first simple_smile

dnolen21:10:48

@thheller: your problem is a bit more subtle than anticipated, I probably won’t get around to it today, too swamped

steveb8n22:10:00

I can wait simple_smile …and there’s plenty more to learn from the om-next-demo etc

dnolen22:10:01

it will require some modifications to the query language, Relay handled this with Unions

dnolen22:10:37

GraphQL I should say

thheller22:10:00

@dnolen dammit I always run into the hard ones first simple_smile

dnolen22:10:16

@thheller: it’s actually not so hard, just want to make sure we do the right thing

dnolen22:10:27

don’t want to rush it

dnolen22:10:02

I got stalled on the syntax, and so backlogged it until next week

thheller22:10:05

yeah understandably. I meant hard for me. can't even wrap my head around the rest of queries yet.

dnolen22:10:38

this covers the Dashboard case

dnolen22:10:11

so we need some syntax for this + some dynamic resolution thing

thheller22:10:05

time for me to read up on graphql then, skipped the details so far.

dnolen22:10:44

oh yeah, if you really want to help out or contribute to Om Next, GraphQL & Relay & JSONGraph will give you big head start on Om Next

dnolen22:10:57

there’s hardly an original idea in it, it’s just all Clojure(Script) idiomatic

tony.kay22:10:25

@dnolen: with regard to figwheel, are you planning to include local state in the reconciler snapshots so that history walking can include transient state changes?

bensu22:10:13

@dnolen: hardly any original idea? queries as data structures form Datalog instead of strings, identity indexing for components, are the first two that come to mind that are not GraphQL/Relay/JSONGraph related

bensu22:10:24

and I haven't read the tutorials yet

dnolen22:10:40

@bensu right there’s fun stuff in the details for sure

tony.kay22:10:19

Hm. I guess that seems antithetical to app state. I guess if there is anything we want to track that needs to be visible in history we just put it into app state and have the mutate methods differentiate between persisted and transient data. Simple enough.

dnolen23:10:31

@tony.kay: no such plans, component local state should be left mostly alone

dnolen23:10:42

trying to do away with is not a good use of time IMO

dnolen23:10:10

however snapshots are an orthogonal concern

dnolen23:10:25

so there’s protocols in place for writing components that put their state somewhere else

dnolen23:10:35

so if you want to override you can

dnolen23:10:46

but it’s not the default

tony.kay23:10:52

I would agree. We are building a "support viewer", and it is nice to be able to see what the user did over time. I'll continue reading the source and see how to go about it

tony.kay23:10:18

A VCR player when someone sends a support request that includes things like server log timestamps and such

dnolen23:10:27

@tony.kay: I have thought it through

dnolen23:10:48

I have a plan for how to record component local state w/ zero support from React

dnolen23:10:52

that’s what killed us last time

dnolen23:10:07

won’t happen again

dnolen23:10:42

but again this more “later” stuff

tony.kay23:10:56

great work, by the way. As soon as I finish grokking the basics, I have a team of paid devs here that are interested in contributing. We're basing our entire dev stack on it.

dnolen23:10:07

@tony.kay: thanks & cool! simple_smile

steve23:10:49

Good point... snippet is better.

steve23:10:09

From above: A newbie question... On every Interval I'd like to increment the app-state counter... and increment a number in the app-state list corresponding to the position indicated by (mod counter (count (list)))