This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-03-28
Channels
- # aatree (1)
- # admin-announcements (5)
- # beginners (5)
- # braid-chat (2)
- # cbus (2)
- # cljs-dev (8)
- # cljsrn (13)
- # clojure (101)
- # clojure-chicago (1)
- # clojure-greece (11)
- # clojure-russia (77)
- # clojure-taiwan (1)
- # clojure-uk (5)
- # clojurescript (73)
- # core-async (5)
- # core-matrix (1)
- # cursive (5)
- # datomic (10)
- # devcards (44)
- # emacs (16)
- # hoplon (207)
- # keechma (5)
- # lein-figwheel (1)
- # leiningen (5)
- # liberator (3)
- # melbourne (1)
- # om (171)
- # onyx (25)
- # parinfer (1)
- # proton (2)
- # re-frame (28)
- # reagent (50)
- # untangled (7)
- # yada (4)
hello! was thinking about how to do 'ttl' caching on data, and the current approach I've thought is -
- store data normally in my app atom
- always return :remote true
from read
- in my send
fn, instead of directly calling a service, also check an in memory cache with ttl innards, and merge
those results in
- an alternate approach, (which iirc is how falcor does it), is to store the ttl timestamp directly in my state atom ,and trigger :remote
only when the data "expires".
what are the pros and cons of either approach? any other alternatives? please and thank you!
when saving, I'd store an expiry time with each entity, and in read
, I'd check that value against current time to decide. it makes read
impure though (unless you include your own 'clock' on env, etc... ugh)
former seems simpler
but yeah, similar to your issue! you'd have to maintain an object (for lack of a better word) that maintains your subscriptions, and updates its configuration based on incoming reads
I see. I want sends when ttl expires even if no reading is happening; different problem?
you could hold on to the merge callback (which you mentioned) and call it when your ttl (for a given subscription) expires and you make a fresh fetch
if alexanderkiel is right about what touch! should do ("...also read from remotes"), then I think maybe solving your problem plus periodic touch! may solve my problem
oh sweet! cmd-r for components! yes!
scary. surely there's a simpler way
no, just a configuration on the cache
in general, I interact with any 'outside world' things in send
- window.history, ajax calls, external caches. even if they're synchronous, I don't access them in mutate action
s. I believe this is the right approach?
you will always do a send, and always call the cb, on every read, which means a merge-novelty! for every read?
...yes? if the data hasn't changed, this should be cheap/no-op? and maybe you could it batch it/optimize at the send layer. I dunno 馃槓
if you have a somewhat deep and wide tree of component data, I don't see how it could be O(1). you need to merge the result of the query into the entire current app state
I could imagine that maybe things are already O(n), so another O(n) is only a constant factor difference
but also conceptually it seems strange to merge novelty for every read, regardless of perf concerns
literally what browsers did pre-ajax, full page/iframe reload? or does that not count
I'm experiencing strange behaviour in 1.0.0-alpha31 where setting an onChange
handler that uses om.next/transact!
on an input
element makes me unable to edit the contents of that input
if the onChange
handler doesn't call om.next/transact!
, (e.g. #(do %)
), the issue goes away
and if I set the value
of the input to the piece of state that I'm manipulating to match the input value, the issue also goes away
is there a way to view the commits between releases on github?
@ethangracer: yes, e.g. between alpha31 and 32: https://github.com/omcljs/om/compare/1.0.0-alpha31...1.0.0-alpha32
thanks
syntax is "https://github.com/<org>/<repo>/compare/<commit, branch or tag>...<commit, branch or tag>"
If any of the keys you put at the end of the transact! mutation query is one of the join keys in your root component's query, then all the props for the whole application go right through. Is that correct?
I think it will still just parse that one key for sends, but it will schedule root for reconciling (which will read the whole thing)
Yeah - the render doesn't happen for all - but that is because React is smart enough??
I mean all the keys are at the root anyway - so all transacts will specify a key that is at the root.
cjmurphy: I think om.next does tree diffing just like om, so shouldComponentUpdate will return false on some child even if the root component gets new porps
(if that鈥檚 what you鈥檙e asking and I鈥檓 not misunderstanding :))
Yeah I'm looking to debug to understand - maybe I'll put some debugging on those other React methods.
my follow on mutate read is causing the root component to rerender rather than the subcomponent I want to rerender. In addition to this, the rerender is happening twice. What could be causing this?
Are you using a keyword for the follow on mutate read? And is that keyword one of those used as a join in the root query?
I've never got idents to work for follow on mutate re-renders so don't know about them.
2. No, it's not explicitly in the root query, but I suppose its still part of the root query since it all composes to root
All my (non-leaf) keys are in the root query because needed to get default db format. So I don't understand how can have a follow on key that is not part of the root query.
cjmurphy: do you have a non-trivial app I could look at? The one thing I'm still concerned about is how to go from app data -> UI tree data. I've got a method that works currently but I'm thinking it might be the wrong approach.
In my 'big app' everthing is rendered too much. So I'm trying to take stock and understand myself. I just did a small app kind of the same and the checkboxes don't all re-render like they do with the big app.
We both need a bigger app to look at where we can study these re-rendering from follow ons (or not - where current component is used). I'm not sure there is such a thing.
my approach has been to query for all the necessary data at the root level such that normalization can occur. the only other root query I have is a "widgets" query that constructs the UI tree https://github.com/seanirby/komokio/blob/master/src/cljs/komokio/parser.cljs#L19-L31 . I think the root rerenders when I try to rerender these UI widgets individually because they don't have a corresponding read function. Not sure though.
That's a serious read defmethod. My approach has been to keep all of them really simple - if state is in default db format then db->tree can be used for everything.
That's the approach Untangled takes I believe - I read that reads are done away with.
cjmurphy: yeah i'm probably doing it wrong , but I thought thats how you were supposed to use db->tree, to construct the UI tree.
We should probably know when it is appropriate to go the simple way or not. As I remember in one tutorial parameterized reads, user being able to sort, that sort of thing - required going off the simple pathway.
Just looked at the Kanban demo and every transact!
is done in the Root component, and none of them have follow-on keys.
Yeah - he goes to a lot of effort to kind of have a 'controller' in the Root component - called App
. So functions are passed down as computed to be able to do this. I chose not to copy that part of the app as seemed like a lot of work. But good for maintenance.
I really like the way he went for simplicity. Not that its all walk in the park - as I remember the sorting / dragging part of it quite involved.
yeah, I don鈥檛 see the kanban demo as very idiomatic for a large app
single large controller is the thing we鈥檙e trying to avoid by having the configurable parser IMO
Yes. But I only know how to write an app where every change makes rendering happen right from the top.
The top level render is going to be called for every single mutate, right? Unless the transact! didnt affect the state atom
The optimization is not calling render for children with queries focused on a part of the tree that was unchanged
That's optimization you talked about before where Om does some diffing. We can't really affect that and that's good I think.
matthavener: oooh ok. I'm not sure where I got the idea that narrowed renders could happen, maybe i made it up
I could be wrong :X
So what's the point of the keys for follow on read in mutates? You could use any random key, would always work the same.
narrow render looks like it happens on set-state!
That makes sense, but local state not really part of Om Next mechanics too much, and good to avoid as a general rule.
How do I trigger a remote read from a local mutation: Does it require specifying it in the mutation, or should Om be able to figure out that something needs to be re-read remotely?
kovasb: I don't know how to fully answer your question but I know the ":value" map you specify in your mutations is whats used to communicate to the what should be reread
@seanirby are you sure the :value returned from mutations actually does anything? i was under the impression it was for doc purposes only, and the only one that had an effect were the ones you passed to the transact! call
@kovasb: your transact!
call must be the same as the example you linked
your parser must know that :thing
is to be re-read on the server
so return :remote true
for that
maybe I'm not understanding the full question
let's assume that the reads following the transaction is :thing
as in the example you linked
are you seeing the parser for :thing
being called after the mutation?
and the send function is never called?
well then that's what you want
the server will perform the mutation and do the remote read
but it gets everything at once
one request
ah, right
so: I have to manually construct the same query as is assembled for me automatically in the base case?
so if you want the full-query
have you tried: (transact! [(some/mutation!) (om/full-query this)])
I'm assuming the full-query
contains the ident
(incidendly, I still dont understand the relationship between these comments and the comments on tony kay's link)
this comment? You can force them to be remote reads by quoting them
look into force
it'll basically call the parser with target
set to the remote
you still have to return :remote true
@kovasb: I'm curious whether my suggestion worked out, I haven't tried it before
i.e. following the mutation with the call to full-query