Fork me on GitHub

On the re-frame SNAPSHOT, I'm getting strange behavior from the debug interceptor. Here's it's output:


only before: is showing what is being navigated into by the path middleware, but only after: is showing me the whole app-db.


Here's the register:

 [rf/debug (rf/path :categorisation :test-response)]
 (fn [tr [_ field new-value]]
   (assoc tr field new-value)))


Hi, is it possible to create an ratom from a subset of a map stored in another ratom? say, for example, one section of app-db ?


I suppose it could be done with a reaction which has the path to the subset of interest embedded within it


But what happens when you do swap! on a ratom that is the result of a reaction ?


i.e., it would need to be R/W; not just R


@johanatan: I think a cursor might be what you’re after?


Mm, yes that sounds right. Is that a re-frame or reagent thing?


Ahh cool. Thx!


@escherize: I can't see any problem with debug here. Seems to be working as intended. I've pushed another SNAPSHOT, because I can't remember the last time I did.


Does it improve things?


I'll take a look. Do you recognize the issue I see in the image of my dev console above?


the stiring at (-> app-db :categorisation :test-response :body) changed from "a xxx " to "a xxx b". I expected debug to say "Here's the old db, heres the new db" Or: Here's the first constrained view of the db, here's the new constrained view of the db.


what happened was: "Here's the old constrained view of the db, and the new view of the entire db" Maybe that is expected behavior though?


debug uses to calculate what it displays.


So that screenshot is saying ... 1. The stuff in "only before" was removed 2. The stuff in "only after" was added


(Not saying if that is right or wrong)


I'm just fiddling around with debug and path in todomvc to make sure when appear to be interacting correctly


If there is a problem it is more likely to be path that's the problem


Any change with the latest SNAPSHOT?


I need to restart figwheel just a sec


but also, the stuff in "only before" wasn't really removed, right? the thing that changed was one value in that map.


and if you were going to say that the map should change when a value changes in it... then "only before" has to contain the entire app-db (or maybe context?)


Hmm. Looking into it further.


does that make sense?


yeah I think you may be right that the path interceptor was suspicious.


Give me 10 mins. There's something wrong with path


Ahh. Now I get it. There's a certain interplay between debug and path - but only if debug is before path in the interceptor chain.


Fixed and new SNAPSHOT up on clojars. In my code, I put debug interceptors to "the right" of path in an interceptor chain. Which is why I hadn't tripped over this interaction.


has anyone done an accordion stuff with re-frame? Like on


I'm thinking of putting together a proposal for a re-frame presentation at Clojure/Conj, I'm just at the ideas stage at this point. Is anyone here interested in giving input or reviewing as the talk develops, or do you have anything particular you would like to see in such a talk?


Reframe seems to be reactive primarily from a UI perspective. That is subscriptions only react when they are tied to a a react-ui component. However, there are plenty of use-cases that aren't UI centric but could benefit from a reactive framework. For example calling a back-end service to fetch additional data. My other comment is that I'm not sure how I can react to multiple data-paths. For example: do a backend service only after the user is logged in AND their GPS coordinates are established. The dispatch mechanism sets one value at a time. The subscribe only works for UI, and is triggered in a singular sense, not by any combinatorial conditions of data. Just curious if others have these issues and if reframe has mechanisms to deal with them.


Or are these concerns that should be dealt with elsewhere?


@fenton: I think you have a bit of a misconception for how re-frame subscriptions work. Subscriptions in re-frame are tied to a piece of data in your app-db, not the state of the UI itself or anything related to the react components of your UI, so you can subscribe to a piece of data that has no effect on your UI.


@shaun-mahood: oh really. i guess i tried it in the past and i thought it didn't run, but only ran when tied to a piece of UI. I'm very glad to be mistaken!


I'll have to test that again!


It definitely takes some getting used to - the most effective thing I did when learning was to put in a very simple "Print app-db" button in the top menu of my app during development that just logged out to the console - I think there are some way better ways to do it now, but it helped me to understand the effects of my changes as I was figuring things out.


I may have messed things up by my defining of :set and :get, but they work for UI stuff, but the following didn't create any console log output?


I have to pick up nephews in 10 minutes....but I'm very interested in this discussion... I'll be back after baby-sitting for sure if i dont resolve before that cutoff! 😞


As far as combinatorial conditions and fetching additional data, I broke all of those down conceptually into individual event handlers and set up some additional checks and data points to make them easier to reason about. I added some additional keys to track my state for some of the more complex areas or that were specific to particular workflows - in the new release it looks like there will be a :dispatch-n option for sequential events (, though that is more on the event processing side.


@fenton: Happy to pick up the conversation later


@shaun-mahood: thanks...I'll take u up on it. The non-UI reactions stuff will be very helpful if I can get it to work! 🙂


any reason dispatch couldn't just be variadic? It's already assuming that each set of event args is already a single seq, so it wouldn't be hard


@fenton that's something I'm interested in too; mostly I'm thinking we need a way to lift the 'behavior' style r/atoms into actual sequences of events. The 'auto-refresh' model of event propagation in re-frame is very nice and easy to use, but only works in a custom execution environment like that provided by reagent in the ui


@fenton @shader Rich Hicky has said that Clojure is 80% functional (compared to something like Haskell which is much closer to 100%). Along the same lines, I'd say that re-frame is 60% reactive (compared to something like Cycle.js which tries to make everything reactive). re-frame apps are fundamentally event driven systems. Things like user clicks and data services callbacks all end up as events. And at that point they should be handled by event handlers and their interceptors/middleware. At that point we are not in a "reactive space", we are in a "mutative space".


Mutations are a bit of a nightmare, so we benefit from applying some order and structure to the process.


I believe you are craving for a means to create internal events. Above, I talked about events being "user clicks a button" or "websockets delivers some data". These are events triggered from the outside - external events. In contrast, think what you are asking for is some way to generate internal events. Like having a rule which says: because path x and y within app-db changed then generate a new event (which will do its own mutation). re-frame currently has no direct support for this, however it has the building blocks to allow you to create it yourself. The on-change middleware/interceptor should act as a template. Steps: - wrap the event handlers which can mutate path x and path y in an interceptor - that interceptor looks to see if they have changed - if they have changed then dispatch an (internal) event. In this way you get a nice "audit trail" of mutations. Everything happens because of events.


So ... while I absolutely love reactive flows, I think they have their place. At this point, I'm not in the cycle.js camp of making everything reactive.


(Although I reserve the right to change my mind on everything, at any time :-))


@fenton: your subscription called data won't work like that. For it to update in that manner it needs to be a part of the UI - that must be what you meant with your assumption that subscriptions require being loaded into the ui to work. Do notice that @(subscribe [:get [:abc]]) in the repl (or in a top level form) would give you the data at that time.


Only defining a function isn't enough to dereference that subscription when it changes.