This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-03-11
Channels
- # admin-announcements (20)
- # beginners (48)
- # boot (90)
- # cider (33)
- # cljs-dev (5)
- # cljsjs (10)
- # cljsrn (7)
- # clojure (68)
- # clojure-austin (5)
- # clojure-bangladesh (4)
- # clojure-finland (10)
- # clojure-gamedev (1)
- # clojure-madison (7)
- # clojure-poland (15)
- # clojure-russia (75)
- # clojurescript (25)
- # core-async (23)
- # cursive (5)
- # data-science (43)
- # datomic (15)
- # dirac (26)
- # editors (10)
- # emacs (2)
- # euroclojure (12)
- # funcool (23)
- # hoplon (7)
- # immutant (68)
- # jobs (24)
- # jobs-discuss (1)
- # juxt (1)
- # keechma (9)
- # ldnclj (7)
- # luminus (66)
- # off-topic (54)
- # om (170)
- # proton (7)
- # re-frame (1)
- # reagent (15)
- # ring-swagger (11)
- # spacemacs (6)
- # testing (1)
- # vim (1)
- # yada (19)
[{:foo/list [:foo/name]}]
this is the correct query to get all the :foo/name
values for all the elements referenced by :foo/list
right?im wondering why doing (om/db->tree [{:foo/list [:foo/name]}] @app-state @app-state)
produces the result {:foo/list [[] []]}
. I can tell that it's correctly picking up that there's two elements in the :foo/list
vector, but it can't seem to find :foo/name
property
I’m just getting started myself, so I’m probably not much help – but, I’d suspect it has something to do with normalization
question of my own: What conditions trigger om next to re-fetch remote data for a query it has already fetched data for?
@seanirby om/db->tree
assumes that you are using the default om database format. so you need to have idents on components so that it can destructure your flat app state into a tree
@chrisfarber: om should re-fetch on read where :remote true
appears in the map that you return on read
shouldn’t matter if it’s already fetched it
ethannavis: so in other words, components which are part of collections need to have an ident?
if you want to normalize them using om’s default database format, yes
which you will almost certainly want to do
the nice thing about om is that it gives you flexibility not to use its default database format if you decide that you don’t want to
though there is significant plumbing built-in to help you use it
ethannavis: regarding the 'plumbing' i know of the reconcilers data normalization, component Ident's, and db->tree. What else is there?
those are the biggest pieces… the only other one I can think of is merge!
, which just uses om/tree->db
Where can I find something that doesn’t assume I know Om or what components mean and what stuff like reify mean?
I can’t find a beginner resource for Om. Even the basic tutorial assumes React knowledge or something.
@urbanslug: Anything that starts with defui
is a component. Behind the scenes it happens to be a React component, but that's largely irrelevant for getting things working. I think a good place to start is just there, with a component being passed props. Look at a devcard of an Om Next component from a project, and try to create a component yourself - passing in a hash-map like devcards do (that's all that props is - a hash-map where the keys are keywords). Just try to do a render function - and see something in your browser. Queries, idents, default db format, all those things can come later once you've got something on the screen. That's one way to start...
Don't need to learn React. The whole props thing is all about immutability. You let React create components for you when it decides the props have changed, something like that...
Actually Om Next might be doing that part and React is all about the diff-ing. Not sure! 😜
cjmurphy: I wish you’d mentioned my username. I’ve been waiting for this reply for long.
Like today I learned that maps are called objects in JS. That is the height of misleading terms.
The term props comes from React - each component has props and children - so same with Om Next components.
Well map is overused - that's why I hope to usually say hashmap when referring to data.
Uh final question, this https://github.com/omcljs/om/wiki/Documentation doesn’t include functions like render
Be careful to know what is Om Next and Om Now (or Prev). defui
is your guide. You were reading about the prior Om. I made that mistake at first. Trouble is it is all on the same website.
@urbanslug: that reference you gave was to Om Previous.
render
is what puts your html on the web page - that's prolly all you need to know 😜
cjmurphy: hahah thanks for the help. I guess I have to work towards migrating this app to Om Next on top of understanding Om
Actually I copy my emoji usage from someone here, but he didn't put a ®️ on it so I'm okay...
Hello, mutation functions need to return a map {:value ... :action ...} I don't understand the purpose of the :value
key. Somebody can help me?
I mean, after a mutate (if I understood) the reconciler merge the new value in the state so why need I a return :value
@raphael: from the quick start tutorial:
Mutations should return a map for :value. This map can contain two keys – :keys and/or :tempids. The :keys vector is a convenience that communicates what read operations should follow a mutation. :tempids will be discussed later.
Hmm but I don't understand, if the data is updated, my component will apply an automatic read no?
yes, but if you need to re-read keys that aren't part of the component's query initiating the transaction, you need to explicitly tell om
section: Why is my component not rerendered after transact!?
however I'm not 100% sure if :keys
work as the tutorial says. I'm putting the re-reads straight into my transaction query
example: [(mutate) :other-key]
if I want to re-read :other-key
What is an om component? https://github.com/omcljs/om/wiki/Conceptual-overview#components not much clarity here
Yes I think it is more nice, since if I don't want to say to my mutation function "don't forget to re-read x y z for my components!" mutation functions don't need to know anything about UI logic. am I wrong?
@raphael: :value :keys
in mutations are just convenience.. The :keys vector is a convenience that communicates what read operations should follow a mutation.
as stated in that sentence
the "communicates" there means person communication, not machine communication
i.e. documentation
so that e.g. a developer that needs to run a mutation written by another team member knows which keys to re-read
This is what I think component is: In Om “component" is a term to mean a piece of encapsulation that contains mutable or immutable piece of UI
@urbanslug: https://clojurians.slack.com/archives/om/p1457694320004941 - that is still Om Previous. Best don't read it or at least be aware - cursors are Om Previous.
@anmonteiro: I noticed Om's source is mostly one ns, is there a particular reason for this? I'm going from a javascript background, where they make different files/different modules as if it's breathing air
@dnolen: I'm going to need access to normalization in the server, I was wondering if I could work on #398 ("normalization functionality should be accessible to server side code")
It's really just code re-org, I'm thinking about having a om.next.impl.db
namespace with tree->db
and db->tree
that both om.next
and om.next.server
depend on
@iwankaramazow: just how clojure namespaces are organized in general
I think at some point some stuff is going to be taken out, as I just asked David about the normalization stuff
ok, thanks for the response!
If one has to use autocomplete feature of https://github.com/JedWatson/react-select with om.next how should one proceed ?. For autocomplete the react-select component is passed a loadOptions
callback which takes as input, the input string and a callback. The callback has to be called with the option-data from the server.
Consider the query: [(:some/key {:param :foo})]
. How does the parser know whether this is a read with params or a mutation with params?
@george.w.singer: keyword vs symbol
Ok. So in all cases reads are forced to have keywords, while mutations are forced to have symbols? Is that a datomic pull syntax custom?
@george.w.singer: Datomic pull doesn't define mutations
Ok -- thanks
see the "Pattern grammar" section
looks like it doesn't define reads either?
I'm not sure what you mean
What I meant by it not defining mutations is that everything is a read
@george.w.singer: it probably came about because mutations look like function calls [(call-this-function ~params)]
yea makes sense
in om/now
, components could be have their initial-state set via the init-state key. What is the best way to acheive this in om/next
? Via om/computed?
@addywaddy: there's initLocalState
(defui X
Object
(initLocalState [this]
{:a 1}))
Hi @anmonteiro yeah, I’m using that. I want to set a number of components as being editable by clicking a link on their parent component. My solution so far has been mapping (value (om/computed props {:editable? editible?}))
, where editable? is the local state of the parent component. But this feels wrong.
should work
OK. I was just surprised that the computed part is present in (om/props this) too, so I’m having to dissoc :om.next/computed before transacting my changes.
Why do you need to dissoc?
@anmonteiro: Sorry - missed your reply. I was transacting the props merged with the updated value, and so didn’t want to store the values under `:om.next/computed in the DB, but I’m being more explicit now about what is being updated.
Hi, I have a child component, and when I do (om/path this)
inside it I get nil
and this is making the component behave incorrectly. Anyone have any tips as to why a child component might end up with a corrupt path and how to troubleshoot it? Thanks!
@drcode: 1. path
is private, I'm curious why you would use it?
2. it will be nil
if you are passing e.g. {}
as props
@drcode: I'm not using it, my app is just breaking and I've narrowed it down to the path being broken
a nil
path will break things
@anmonteiro: is path from path-meta? so if you modify the props in some way that would lose metadata?
@hueyp: Haven't studied class-path yet, all I know is I have a nested component with props.omcljs$path = null
@drcode: hrm, do you have a list in the app state?
or just vectors & maps?
@hueyp @anmontiero: Thanks, sounds like clobbered metadata is where I need to focus my attention
@anmonteiro just vectors and map
yah, I think I just do get
to pass props from parent to child but I could see maybe if you do some processing on them first? (which might be a bad idea?)
@drcode: if you are putting metadata in props, make sure to vary-meta
, not with-meta
?
Stupid question: If I create a component whith om/factory, I'm allowed to use that multiple times in my UI, right?
definitely
Thanks, you guys are super helpful, I'm sure this info will help me resolve my problem!
I'm curious about the root cause if you end up finding it
@anmonteiro: Your hunch was correct... I had a key in the state that didn't contain anything yet, but instead of initializing it to {}
I just didn't bother defining it. Simply initializing it with {}
fixed my problem.
It seems rather counterintuitive that having a missing key in the state would cause a UI element to forget its path, might be good to have an error message for such situations.
Hmm. Some of our data comes from Pusher channels, which we have to subscribe to and unsubscribe from as the user navigates. It occurs to me that the set of channels we need at any moment can be derived from the component queries. Is there a good place to notice that the queries have changed and recalculate which Pusher channels we should be subscribed to?
@anmonteiro: can we rebase the PR for 650? thanks
@dnolen: definitely. give me a few minutes
btw, did you see my question wrt. #398 (server side normalization) earlier?
@dnolen: rebased
Hi! if somebody has some spare time, I am fighting with the render hints of om/transact!
which are causing the parser to be executed several times
I made a small gist https://gist.github.com/fterrier/b5359d092a87ca1f1cf3
I have a 2 independant "leaf" components of my tree relying on the same underlying value, so when I'm updating that value I'd like to re-render everything
@franz: the parser is run once for local reads and once for every remote
there's always one implicit remote
mm, calling (om/transact! '[(test/weird) :test])
results in my read function being called 4 times in total
@franz: the component which transacts is queued for re-render. reading :test
will queue the component which has that key
so 2 reads for the component which transacts, 2 reads for the component which has the :test
key
I'm trying to optimise that, because in the original project, I'm doing some "heavier" computation in the read function
but if I understand properly, the bottomline is that the read function should be really fast then
franz: I’d say so.. read/parser functions are synchronous so your UI will be blocked until a slow read finishes.. if the computation is really heavy you could ‘send’ to a webworker and then merge the result back in for a quick read
franz: in your reader, (:target env) will either be :remote or nil, so you could just ignore the read call if its :remote
or better, you can probably do :remotes [] in your reconciler config
franz: so you can send different remote queries to different remotes
or read locally