Fork me on GitHub
#om
<
2016-03-21
>
urbanslug12:03:51

Is owner a cursor?

dnolen12:03:41

@urbanslug: in the the previous version of Om, owner is the backing React component

urbanslug12:03:50

@dnolen: Thanks, I expected that because that’s what the docs say. I guess reading someone’s code gets a little confusing. When we talk about a cursor being an atom that maintains path information to the app state what do we mean exactly?

urbanslug12:03:01

I am using the previous version of Om

urbanslug12:03:36

Also how will the cursor know what the component wants.

dnolen12:03:14

@urbanslug: it doesn’t know what the component wants

dnolen12:03:48

cursors are just wrappers around maps / vectors so that you can pass around “slices” of the entire app state to components

urbanslug12:03:43

So a cursor is just the subset of a map(this map being the app-state) that we pass to the component?

urbanslug12:03:52

That’s simple enough.

dnolen12:03:38

yes more or less

urbanslug12:03:48

The word “path” in the docs is rather confusing.

dnolen12:03:21

cursors maintain a path to where they actually exist in the app state

dnolen12:03:35

in this way components can update the app state without explicitly sharing path information

urbanslug13:03:33

Oh I see, the cursor is a data structure that is a "pointer" to a part app-state. Therefore changes in this “pointer" affect the app-state and the component only cares about what it sees. It will not care about the app-state.

urbanslug13:03:33

I wonder how much it hurts for Nolen to repeat this every time for beginners, maybe there’s a need for #om-beginners ?

urbanslug13:03:44

Last question, do sub cursors maintain path info the the parent cursor or the root atom i.e app-state

thiagofm13:03:48

@urbanslug: I think for that reason we can write docs, blog posts and so on to help people to digest how it does work.

urbanslug13:03:18

@thiagofm: I have updated the docs a little going by my understanding of what I am learning and to help other almost 100% beginners.https://github.com/omcljs/om/wiki/Cursors#overview

urbanslug13:03:34

Maybe you can give it a fix if you feel that I am wrong.

urbanslug13:03:37

Whatever you want.

thiagofm13:03:49

It looks good

thiagofm13:03:43

I'm personally not the best person to judge om docs, as I'm mostly only toying around with om next which you don't have to use cursors

urbanslug13:03:18

Oh okay, thanks simple_smile

thiagofm13:03:51

I wonder if cursors are more a clojure thing than a Om thing -- I've used other kinds of libraries where you can use a cursor for example to navigate through a configuration data structure.

urbanslug13:03:34

I don’t know.

matthavener14:03:07

thiagofm: ‘cursor’ also has meaning in SQL databases https://en.wikipedia.org/wiki/Cursor_(databases)

thiagofm14:03:38

@matthavener: I think there are many areas in computing that use the term, like mouse cursor and so on.

michaelr15:03:45

why does the above return false?

matthavener15:03:48

michaelr: I think the component needs to be created via om, because component? checks if its an om component, not just any React component

michaelr15:03:53

matthavener: do you know how it should be created by om?

michaelr15:03:22

some function in the API which I could use too?

matthavener15:03:54

hrm, actually I think I’m wrong, or confused simple_smile that seems like it should work

michaelr16:03:31

(set-query!) has a (component?) precondition, that's why i'm asking

michaelr16:03:48

it fails when i try to set-query!

thiagofm16:03:42

I think set-query! is meant to be used inside the HelloWorld component, like (om/set-query! this ...)

thiagofm16:03:17

And (component?) might be only true in that case. Maybe check the source code for the component? function?

michaelr16:03:59

(om/component? (.-prototype HelloWorld)) returns true

anmonteiro16:03:46

@michaelr: that code should return true if the instance was created

anmonteiro16:03:01

om/factory calls React.createElement inside

michaelr16:03:56

i thought that by calling (hello) i'm creating the instance..

anmonteiro16:03:01

by calling (hello) you are calling React.createElement. we don't have control over when the instance is actually created

michaelr16:03:33

so when i want to set the query params of a component, that component should already be rendered?

anmonteiro16:03:44

@michaelr: you can see that this returns true: (om/component? (HelloWorld.))

anmonteiro16:03:06

but you should not be doing that. It'll break things.

anmonteiro16:03:15

@michaelr: if you want to define the params of a component without being rendered, doesn't defining it in the params function work for you?

michaelr16:03:06

well, it has to be dynamic..

michaelr16:03:46

it's a chat app, suppose that i'd like to display chat #1

michaelr16:03:12

so i thought i'd set :chat-id param to 1 using set-query

anmonteiro16:03:49

not sure what :chat-id is, but isn't that something that could be put in an ident?

michaelr16:03:24

sounds like ident should do it, though i still don't understand how to use it.. will get back to the tutorial

andrewboltachev17:03:11

Hi. Question on Om Next source: can anyone explain what this line is doing? https://github.com/omcljs/om/blob/master/src/main/om/next.cljs#L1824 Wouldn't it be calling (instrument instrument), having instrument not to be nil?

anmonteiro17:03:32

@andrewboltachev: it's not calling a function, but creating it

andrewboltachev17:03:43

@anmonteiro: Thanks. I'll try to macroexpand once again simple_smile

anmonteiro17:03:58

@andrewboltachev: just try running this at the REPL

anmonteiro17:03:06

(def x 3)
(cond-> x (not (nil? x)) (fn [x] (inc x)))

anmonteiro17:03:12

you get a function back

andrewboltachev17:03:07

yep I did it like this... but doesn't it do (-> x (fn [x] (inc x)))?

anmonteiro17:03:45

which is (fn x [x] (inc x))

andrewboltachev17:03:47

ah, and x would be name?

shofetim17:03:32

I'm working on an Om (classic) app, and cannot seem to bind to onplay events on a video element. onclick and all other events work, and if I bind plain JS to the video tag it fires, yet nothing in Om. I can't find any known bugs about it in react or Om, anyone see this before?

andrewboltachev17:03:21

Ah... it's just like @wraps in Python. I.e. this function would have the same name as original one had, but would be ran in another environment (i.e. with instrument bind to nil). Bingo!

andrewboltachev17:03:55

(and this would be useful for stacktraces etc)

andrewboltachev17:03:59

@shofetim: How do you bind plain JS? Can you show the code?

michaelr17:03:15

@anmonteiro: not sure whether om/Ident will help in my case. i have a list of items, the user clicks on one of the items and then i should display a detailed view of that item only..

michaelr17:03:35

so i have the item id when the user clicks on it, now i was thinking to set the detailed view's query params to that id

andrewboltachev17:03:19

@michaelr: I'm not sure if it would help, but you might check how I did routing example with set-query! https://github.com/andrewboltachev/omnext-routing-one/

shofetim17:03:27

@andrewboltachev: This works https://gist.github.com/b7ee7bf902e573827fe3 though it ugly to use the did mount and JS interopt...

michaelr17:03:57

andrewboltachev: thanks will check now

andrewboltachev17:03:37

@shofetim: Would this work in React btw? onplay attribute?

shofetim17:03:58

@andrewboltachev: I haven't tried it in plain React, it aught to work (clearly the onplay event is firing, and is part of the spec https://dev.w3.org/html5/spec-author-view/video.html it just isn't passed through either Om's or React's event system.

andrewboltachev17:03:53

@shofetim: There's huge, Slack-like React community on some platform... I just fogertting the name of it every time (it's not Slack). You should ask there, telling that you ain't using JSX, but JS functions directly (they don't know about Clojure) and they should tell on how to workaround this attribute. Please share your experience with us then.

iwankaramazow18:03:50

@michaelr: to answer your question: if your root component doesn't need queries, you should either: a) place the query of the child on the root, the child should be a function. In this case the child doesn't actually need a query. b) compose the child's query in the root with a join-query

iwankaramazow18:03:47

I would go with a), too many joins to make queries compose give you some extra work in the parser

iwankaramazow18:03:56

for example my router composes everything with [{:route-root [...subquery]}]

iwankaramazow19:03:52

This has some disadvantages, like things merge under :route-root

iwankaramazow19:03:31

this is just an arbitrary chosen name to compose queries

iwankaramazow19:03:10

In most parser methods I have (get-in @state [:route-root :real-key])

iwankaramazow19:03:22

:route-root pollutes my app-state...

iwankaramazow19:03:43

Ofcourse this is a situation where you can't do it without a join

hlolli19:03:22

has anyone made any demo of cljsjs react-motion and om.next? Nevermind, found one here: https://github.com/bendyorke/dinosaurus-rex/blob/4fd5035496f076bc864b0a660ea4133c032841fe/src/dinosaurus_rex/core.cljs

thiagofm19:03:54

No matter what I do I can't manage to use set-query! 😞

thiagofm19:03:01

I've created a project from scratch...

thiagofm19:03:19

(defui ^:once Code static om/IQueryParams (params [this] {:language "haskell"}) static om/IQuery (query [this] '[(:code {:query ?language})]) Object (render [this] (let [{:keys [code]} (om/props this)] (om/set-query! this {:params {:language "ruby"}}) (dom/div #js {:id "code"} code)))) I get: next.cljs?rel=1458501277272:1149 Uncaught #error {:message "No queries exist for component path (haxlife.components.window/Window haxlife.components.code/Code)", :data {:type :om.next/no-queries}}

thiagofm19:03:28

If I try to (.log js/console (pr-str (om/full-query this))), I get the same message

andrewboltachev19:03:31

@thiagofm: replace Ruby with Python and it would work You rather try to use set-query! on root component, there's metadata and some other little things in play

andrewboltachev19:03:12

@thiagofm: I can also suggest to check this example of mine: https://github.com/andrewboltachev/omnext-routing-one Code isn't that pretty, though

thiagofm19:03:26

Wow, it only works in the root component

thiagofm19:03:48

I don't necessarily want to do routing

andrewboltachev19:03:46

But probably yes — on Root comp only. It's even worse in fact — I don't know, would child queries be used or not at all

andrewboltachev19:03:32

'cause that's you who passes data to them: (render [this] ... ((om/factory ChildComponent) mydata))

thiagofm19:03:54

So even though my "code" component might be really nested down

thiagofm19:03:12

I have to figure out whether I want to do X or Y in the root component?

andrewboltachev19:03:52

For me it seems like that now

andrewboltachev19:03:51

You might ask more experienced guys though

thiagofm19:03:50

I mean, it makes sense

thiagofm19:03:59

I've probably tried every combination possible

andrewboltachev19:03:18

Aha, so you've got the same feeling

thiagofm19:03:30

I had even trashed my previous project

thiagofm19:03:49

Because I thought it was a problem perhaps because of datascript

thiagofm19:03:58

(which doesn't have anything to do with it)

andrewboltachev19:03:27

I'm now going through Om Next's source code, but it's not that easy. and would take some time to do

andrewboltachev19:03:11

I hope I would be able to understand it better/implement my own ideas or even contribute then

thiagofm19:03:50

I guess I'll have to do this at some point

thiagofm19:03:54

Oh well, I can move on given that, thanks a lot!

iwankaramazow20:03:54

@thiagofm: the error you get, is from an invalid query that doesn't compose

iwankaramazow20:03:09

I posted something about this yesterday here on Slack

iwankaramazow20:03:17

scroll back for a longer explanation

michaelr20:03:06

andrewboltachev: thanks for sending me the example, i think i understood it. though right now it would be great if someone knowledgeable could confirm that this is the way to implement the master-detail

michaelr20:03:51

@iwankaramazow: routing, and query composition is my yesterday's question simple_smile

andrewboltachev20:03:55

@michaelr: Yep I agree. Thanks for sharing your experience with it

michaelr20:03:03

today i'm trying to figure out the right way to implement master-detail, such that a user clicks on an item in a list and a detailed screen is displayed for that item. not sure what's the right way to pass item id to the details screen.. or should i say, how to pass it to the query?

drcode21:03:26

@michaeldr: So it's sounds like you're maybe trying to do things in the components that you should be doing in the parser- My impression is that you'd want to have the detail component just have its own branch inside the parent (like named :detail) and then the detail component just automagically gets the stuff it needs to do its job, because the parser functions take care of the id resolution. If you really need the ID in there (like because it's needed to create a mutation in the detail component) then it is just one of the properties inside the :detail branch of the query tree

drcode21:03:01

@michaeldr: So a SINGLE entity in the state may have MULTIPLE entities in the UI tree (i.e. the master entity with a branch inside it for the detail entity)

michaelr21:03:16

it's funny i was about to write that that i think i found what i need, switched tabs and there you wrote it too simple_smile

michaelr21:03:35

found this line ^

michaelr21:03:59

it has a :current-tab, which i think is more or less what you suggest

michaelr21:03:30

drcode: what do you think?

drcode21:03:31

@michaeldr: Yeah, I think that's the same sort of idea: The important thing is to make the components STUPID and the parsers SMART.

michaelr21:03:17

yep, stupid worth lot's more than smart at times

thiagofm21:03:48

@drcode: is this Conrad Barski?

thiagofm21:03:15

Wow! I love LOL, best book ever

adamkowalski21:03:48

hey how do you deal with a websocket connection in om next? do you use a core async channel or do you do everything through the reconciler

adamkowalski22:03:39

because I was thinking about initializing a websocket and a core async channel, then for each of the callbacks (onerror, onopen, onmessage, etc) have a channel. That way the callback would just relay the work over to the core async channel and I don’t need to worry about the socket at all

michaelr22:03:58

interesting.. (om/component? (om/app-root omnext/reconciler)) returns false

michaelr22:03:13

and this fails: (om/set-query! (om/app-root omnext/reconciler) {:query [{(in/get-name component) (om/get-query component)}]})

michaelr22:03:32

this does something: (om/set-query! omnext/reconciler {:query [{(in/get-name component) (om/get-query component)}]})

michaelr22:03:37

but doesn't seem to replace the query

drcode22:03:36

Server streaming is all explained here: https://github.com/omcljs/om/wiki/Server-Streaming (Someday hopefully simple_smile )

adamkowalski22:03:54

it just says soon

drcode22:03:10

Unfortunately true... I've been looking forward to the designers' thoughts about it since last November...

drcode22:03:55

@adamkowalski: Though your core.async approach sounds pretty sensible

michaelr22:03:38

but this does work: (om/set-query! this {:query '[:what]})

michaelr22:03:48

when calling from root's render method

michaelr22:03:47

and this works too: (om/set-query! (om/class->any omnext/reconciler something.core/AppRoot) {:query '[:whatssss]})

adamkowalski22:03:04

@drcode: actually i just tried making a basic demo which didn’t even use core async and it was surprisingly simple

adamkowalski22:03:37

essentially i would start with a state atom that had a websocket key and a nil value

adamkowalski22:03:01

then I would have a mutation called open socket, which would handle setting up the socket and registered callbacks for the different events

adamkowalski22:03:40

those events would actually call another transaction based on the event that had happened

adamkowalski22:03:08

for example onmessage would trigger a transaction with the message as the parameter, so everything is fully decoupled

adamkowalski22:03:44

finally I have a close socket mutation which handles tearing everything down and sets the websockets value in the state map back to nil