This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-11-16
Channels
- # admin-announcements (9)
- # beginners (112)
- # boot (223)
- # cbus (10)
- # cider (19)
- # clara (2)
- # cljs-dev (81)
- # cljsjs (3)
- # cljsrn (45)
- # clojure (239)
- # clojure-conj (12)
- # clojure-poland (2)
- # clojure-russia (56)
- # clojure-taiwan (1)
- # clojurescript (57)
- # cursive (28)
- # datomic (5)
- # events (14)
- # immutant (1)
- # jobs (1)
- # ldnclj (8)
- # off-topic (28)
- # om (80)
- # onyx (121)
- # re-frame (10)
- # sneer-br (1)
- # spacemacs (40)
- # yada (44)
In my app, a component represents an autocomplete search (customer-search). For this search it queries for all customers by name. In this case, i made a :shared value that is a filtered database:
(def reconciler
(om/reconciler
{:state conn
:shared {:customer-db (d/filter @conn
(fn [_ datom]
(= (.-a datom) :customer/name)))}
:parser (om/parser {:read read :mutate mutate})}))
. As far as i understand, i need to rerender the root, if i want to update the :shared values. correct?@thomasdeutsch: to update shared, yes
@thomasdeutsch: My understanding is that you must used :shared-fn to apply updates, which will merge into :shared. I
I'm working on :shared-fn today, so I'll pipe up if I find anything otherwise, or any gotchas.
@dnolen: experimenting with :shared-fn
, and I'm finding it does not get called when the root component is re-rendered, only when (om/add-root! ...)
is executed. Is that intended behavior?
@bplatz: this is probably an edge case where the root component gets updated directly instead of just calling the root render fn
@leontalbot yes, it works
@andlai There you go!
if iām working with datomic, itās unclear to me how iād resolve tempids when my transaction is wrapped in a thunk:
(defmethod mutate 'item/create
[{:keys [conn]} _ {:keys item/om-tempid}]
(let [db-tempid (d/tempid :db.part/user)]
{:action (fn [] @(d/transact conn [{:db/id db-tempid :foo "bar"}]))
:value {:tempids {[:item/by-id om-tempid]
[:item/by-id resolved-db-id]}}})) ;; how to resolve db-tempid?
anyone else run into this yet?
@joshfrench: So, that is Datomic server side mutate, right? (not Datascript)
@tony.kay correct
I don't think you have to put the transact in action. The parser calls the action on return, but that has to do (I think) with the UI concern on the client
that was my best guess: run the transaction above and just deref it in the return. but i wasnāt sure if that was allowed server-side.
ĀÆ\(ć)/ĀÆ
it is meant for side-effects on app state is my understanding, and there is no "app state" on the server
you can prepend /shrug to anything in slack!
so are there any working examples of tempid migration out there? i was looking at https://github.com/Jannis/copaste but i canāt get it running and iām hitting the limits of what i can glean just by reading code
Any thoughts on differentiating between refs and vectors in read implementations in order to support writing a recursive parser that automatically follows refs? I was hoping I could annotate my idents with meta data and the refs in the state (put there by tree->db
) would preserve the metadata from ident but that seems not the be the case.
This works for my current data but is really dirty and falls down for data that looks like a ref
(defn ref?
[val]
(and (vector? val)
(= 2 (count val))
(keyword? (first val))
(not-any? map? val)))
I am coming from js react and new to om.next. I have a textarea in an om.next component with an :onChange handler which updates local state using om/update-state!
This triggers a render of the component so that the value of the textarea changes in the browser as I type. All good and as per js react.
However the properties of the component, which were there for the initial render, seem to be lost on the subsequent renders caused by the update-state. Is this expected? Do I have to copy all the props to state? Or does it just sound like I need to look harder at my code? Thanks.
@colinf: I donāt think your props should ever get lost, and you should never have to copy props to state. Its hard to know whats wrong without knowing more about your code. Are you using Om as shown on the readme or trying out Om.next?
@colinf I have a very simple om.next example that does onChange https://github.com/griffio/om-next-01 https://github.com/griffio/om-next-01/blob/master/src/om_next_01/core.cljs.
colinf: I suspect it is something with your read impl. Iāve had similar problems but canāt remember what caused it. I would make sure that you can call your parser manually with your root query after your app gets mounted and ensure that it gets the right data. If your read fn isnāt finding the correct data in the app state on reads after the first on I think you would have this problem (so update-state!
might not be relevant except that it is exposing the problem by causing the re-render).
@griffio: Cool - thanks for that. You have used om/transact! to update app-state for each text keystroke. My failing code uses om/update! for each keystroke and then om/transact! to update app-state only on keydown of enter (i.e. data entry finished). I can try your way to see if that eliminates the problem.
which is why I think it is something to do with how you read the data from your state
@noonian: It took me quite a while to get my mind round the reads with composed queries and recursive parsing, so I wonāt be surprised if the problem is in there! This component has no query - it is passed the initial props from itās parent which seems to work fine for the initial render but then not after an update-state. Maybe I can also try rolling the data entry component up into its parent.
Hmm, Iām not sure then. It could also be a bug in Om. The re-rendering code may not have been exercised that much for components without queries that have component local state.
@noonian: I added a query to the component and it works fine now. In my tiny mind I didnāt need to query as I had already āreadā the data in the root query i.e. there was no new data involved. But I obviously need to think differently! Cheers
Om does support query-less (reusable) components though. It would be nice to know why your component wasnāt receiving its data.
@noonian: I may stumble across an explanation while finishing my experiment with om.next, but if not I will try to isolate the issue
@joshfrench: Sorry, that copaste experiment is very much WIP. If you pull the latest master, you should be able to get it running with GIT_DIR=/tmp/copaste-store.git git init && boot run-development
@jannis how do i make clj-consonant
available? boot install
throws "java.lang.Exception: can't find jar fileā even after i run boot jar
. (sorry, totally new to boot.)
@joshfrench: Ah, of course, it's not on clojars. You can clone it from
and install it locally using boot deploy
when inside the repo.
boot deploy
is what i was missing, thanks again!
super helpful to see some of this in action, this is great. much obliged.
@jannis: whats the consonant thing this is a clj version of?
@joshfrench: Not sure how much you can learn about tempids by looking at it though. I'm simply taking the UUID portion of the tempid, use that as the real ID, store it with that ID on the server and then return the pair. How you do it depends on the data store. Some may allow you to create the ID post-creation, others return the created entity with the real ID...
@martinklepsch: http://gezeiten.org/~jannis/consonant.pdf - it's something I drafted quite a while ago š
@jannis right now iām seeing what sounds like a bug you ran into, where migrating actually destroys my local tables. but iām up to date on transit, so i donāt think itās the same root cause. iām hoping to spot some obvious difference in the actual behavior here, now that i can see what youāre sending/receiving.
@martinklepsch: I'm toying with the idea again to see if I can simplify the concept somewhat and make it more Clojure-friendly. Not sure how much of a point there is since there's Datomic but it's bugging me that I never got to finish implementing it.
@joshfrench: I'm using a custom merge tree function. The default one doesn't perform a deep-merge of maps.
i saw that, i wasnāt sure why though. sounds promising, iāll have to dig in.
@joshfrench: So if you have something like {:people {5 {:id 5 :name "John"}}}
, returning {:people {6 {:id 6 :name "John"}}}
from the server will simply replace the value of :people
.
While what you may want (depends on your tree structure) is to a few levels deeper to maintain local properties and temporary local people.
may have to do with the fact that iām not returning anything except tempids
which might be a mistake?
in other words iām not returning :keys
here: https://github.com/Jannis/copaste/blob/89126060a1785a93fb91aed28c0e76b60ab0ccf9/src/server/parsing/copaste.clj#L88-L90
Could be. I'm trying to remember whether the server-side :keys
returned via :value
are used or not. On the client-side they are ignored.
right
iām not, and it is not š
but lots to try here, and i can reduce it to something showable if none of them work.
If all you do is call (om/transact! foo '[(app/create-your-thing)])
with no reads and you're returning :tempids
, it shouldn't throw everything away. It should only migrate to the real ID.
@joshfrench: It expects your data to be structured like {:items [[item-by-id 1] ...] :item-by-id {1 {:id 1 ...} 2 {:id 2 ...}}}
. Perhaps that's your poblem. Also, are you aware of :id-key
(reconciler option)?
normalization doesnāt seem to be the problem, everything is properly normalized up until i migrate. and i tried :id-key
with no luck.
actually post-migration everything is still normalized, just nilled out all the way down the tree.
another good theory. iāll have to spend some time reducing this.