@tolitius: ah, just got back to this. Does your solution only update the states when mount/stop and mount/start are called?
I'm using re-frame for my front end and I want to change some mutable fields on the webrtc javascript object when my app-db is updated
so setting fields on the mutable webrtc object isn't something that just happens on mount start, it happens throughout the lifecycle of the component.
@jiangts: if the map is {:socketURL (config :some-url) :onstream (config :on-stream-fn)}
, then after you change the config
and do
(mount/stop #'app/config)
(mount/start #'app/config)
the map will have updated values since it calls into config
to get them every time. unless I am missing something in your use case (I have not used reframe)right, I gathered the above code would update the fields. However, I thought it'd be cleaner if I didn't have to explicitly call mount/stop
and mount/start
every time I wanted to update the fields
for example, for the webrtc library i'm using, the user can toggle whether or not they want to stream audio, video, or both
the js library handles it by mutating a field
I want the user to be able to click on buttons on the user interface to alter what the field contains to get the right behavior from webrtc
personally it feels a bit heavy handed to have to call mount/stop
and mount/start
each time a user clicks such a button
of course, I am with you.. however I can't really connect it to mount
why can't that map be just an atom with watchers?
i.e. not a defstate
yeah that's what i'm doing now lol. 😛
or actually, I'm putting an atom into the defstate
the reason i'm doing that is because adding a watch feels stateful to me, so i want that to be managed by mount
so on :start
it can add the watch and on :stop
it can remove it
I see.. so the reason you want this map to be a mount's state is to add a lifecycle to this atom to add/remove watcher, right?
right
ok, and right now you do have it working by having a
(defstate my-map :start (create-atom-with-watcher) :stop (remove-watcher-and-reset-atom my-map)
?yes. the create-atom-with-watcher
function returns an atom
and instead you'd like it to be? 🙂
I guess it works at this point, I just hadn't figured it out when I first asked hte question 🙂 haha
I haven't used mount much, so the double deref @@
feels a bit ugly to me, but otherwise it works fine!
I saw the double deref in the datalog code example for cljs so I'm guessing it's acceptable enough
hold on, but
(defstate my-map :start (create-atom-with-watcher) :stop (remove-watcher-and-reset-atom my-map)
does not use @@
right, it is just an atom with a watcher?ah, not that code. I guess I never explicitly @@
, but it's just something I need to keep in mind. For example, now I need to make sure I swap!
on a @my-map
rather than just on my-map
But I think it's fine, I just had to figure out this pattern 🙂
thanks!! btw the clj(s) community is incredible, I almost never get to talk to library maintainers!!
right (swap! @my-map fn)
since it is cljs
: i.e. the state is derefable
ah, right! I forgot in the clj
version you do not need to deref the state.
right, so @
in cljc-mode
is consistent accross cljs
and clj
but if you would have used mount for strictly clj
side of things, you would just do (swap! my-map fn)
there are a bit more details here: https://github.com/tolitius/mount/blob/master/doc/clojurescript.md#managing-state-in-clojurescript
I think your approach with
(defstate my-map :start (create-atom-with-watcher) :stop (remove-watcher-and-reset-atom my-map)
where (create-atom-with-watcher)
creates a regular atom with a watcher is a fine solutiongotcha. thanks for clarifying!
sure, very welcome 🙂 let me know if you'd have more questions / thoughts