This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-07-04
Channels
- # admin-announcements (14)
- # aleph (3)
- # beginners (75)
- # boot (95)
- # carry (4)
- # cider (23)
- # clojure (39)
- # clojure-android (3)
- # clojure-brasil (2)
- # clojure-dev (17)
- # clojure-gamedev (1)
- # clojure-mexico (12)
- # clojure-poland (12)
- # clojure-romania (1)
- # clojure-russia (10)
- # clojure-spec (8)
- # clojure-uk (36)
- # clojurescript (34)
- # core-async (4)
- # datomic (40)
- # emacs (1)
- # events (7)
- # hoplon (119)
- # instaparse (52)
- # keechma (71)
- # mount (4)
- # off-topic (9)
- # om (4)
- # onyx (3)
- # other-languages (23)
- # protorepl (3)
- # re-frame (9)
- # reagent (26)
- # rethinkdb (5)
- # spacemacs (2)
- # testing (1)
- # yada (1)
@gowder: don’t have time to read it all, but sounds like maybe you’re dereffing the ratom in the wrong place, so Reagent doesn’t know to re-render when it changes
@danielcompton that sounds pretty likely. I don't really understand how reagent render-on-derefs play with closures and let bindings... thanks. will experiment moving it around some
weirdly enough, it wasn't the deref after all. It was hanging the keyboard listener. Hanging it within the render function rather than outside it worked. I'm not quite sure why...
Comparison: Broken:
(defn footnote [text page]
(do
(swap! footnote-counter inc)
(let [modal-state (atom false)
num @footnote-counter]
(listen js/window "keypress" #(handle-footnote-key % num page modal-state))
(fn [text]
[:span
[footnote-flag num modal-state text]
[modal-content text modal-state page]]))))
Working:
(defn footnote [text page]
(do
(swap! footnote-counter inc)
(let [modal-state (atom false)
num @footnote-counter]
(fn [text]
(do
(listen js/window "keypress" #(handle-footnote-key % num page modal-state))
[:span
[footnote-flag num modal-state text]
[modal-content text modal-state page]])))))
I'm really not sure why though. I guess maybe because in the new version, on re-render it re-hangs the event listeners or something (???)(defn footnote [text page]
(do
(swap! footnote-counter inc)
(let [modal-state (atom false) ]
(listen js/window "keypress" #(handle-footnote-key % num page modal-state))
(fn [text]
(let [num @footnote-counter]
[:span
[footnote-flag num modal-state text]
[modal-content text modal-state page]])))))
You want the render fn
to rerun whenver footnote-counter
is reset with a new value. The ONLY way to make that happen is to deref it inside the fn
At the bottom of this page there are some reagent tutorials, have a read through them:
https://github.com/Day8/re-frame/wiki
In particular, look at When do components update
thank you @mikethompson
I finally got it going properly ---the issue wasn't rendering the individual footnote elements but getting rid of the event listener that I hung on the global window for each footnote, which I think were interfering with one another. In case you're curious, after squashing a few more bugs, it turned into the last 2/3 of this namespace: https://github.com/paultopia/stdio/blob/master/stdio/src/stdio/shell.cljs
I doubt you have got it working properly
num @footnote-counter
is in the wrong place, I promise ( I can't comment on the rest because I don't understand the code or its purpose).
Anyways, have a look at those Wiki turotials
The purpose of the footnote counter is not to be re-rendered on its own, just when the outer component (like the whole page) is rendered. It's just to allow me to keep a running total of footnotes in each outer component so that I can just slap new footnotes in and have them be number 1, 2, 3, etc. instead of all the same number. So, believe it or not, I actually meant to close over the value of the number on first render... and actually learned the trick by negative implication from what the wonderful re-frame tutorials said not to do 🙂 ... It wouldn't even need to be stored in any kind of state at all, except that I wanted to be able to not have to number footnotes by hand. (Think of it as code generation perhaps? A poor man's macro?) And it is working as intended now. But, I will definitely study those tutorials more! I really really appreciate your taking the time to help.
Does anyone have a good pattern for reloading data after mutations? A common pattern for me is that I POST some via a click handler inside a component, but now I have to get the component to reload its data, which I have to do in the case of success/error. Or is this something that Om.Next is trying to solve?
@petrus: i have several approaches to that in my (re-frame) app... for simpler cases i return the updated objects in the response of the POST. for some cases we have an observer-pattern over a websocket, and for some cases we just let data expire from cache and accept it will be outdated for a while
@mccraigmccraig, can you share your websocket implementation? It seems you need to design some data path/naming conventions and have some kind of page-level “data subscription"
Even though I am returning the updated object, it’s admin to know where to put it
And preferably I’d like to tie it all into the component
@petrus: the websocket has a core.async
go loop which gets messages with [:tag value]
format, and dispatches to a handler based on :tag
... mostly those handlers destructure stuff out of the value
into re-frame event dispatch
es
You must have a subscription somewhere that knows where to look in app-db for the latest value of a given entity?
yes, i have paths in app-db like ... <type> <id>
oh, and i use metadata on objects in app-db to indicate retrieval times, so i can later make a decision on whether freshen an object or just use the cached version