Regarding your point 2 ... the first formulation is only "bad" because that's not the way it is done. If you want to create a subscription which depends on another subscription you do it the second way. There's not much more to be said. That's the way re-frame subscriptions are designed.
Regarding your point 1 ... nothing jumps out as being wrong ... it is a bit hard to tell without more information
Have you installed re-frame-10x?
Ugh , I can see the problem now. So odd I couldn't see it before. The args to your signal function are incorrect
(fn [[_ row col] _]
[(subscribe [:piece row col])])
@rnait1977 ^^
Yes I do have devtools. Made the change in the code. Works like a charm ! Thank you Mike š
It tells you what values subscriptions return
And I suspect that will give you more insight
OUR you could just add some print
in there to give visibility
add +10x
when using that template
Ie. use lein new re-frame py_project +calva +10x`
https://github.com/day8/re-frame-template#open-10x-panel-if-using-10x
Good. thanks Mike. I'm going to try this
So I installed 10x and I tracked the subscriptions. :piece_image x y is a subscription that returns a path to an image to render a black pawn or a white pawn in the cell x y. :piece x y is a subscribtion that gives me all the data about the piece that is in cell x y Here are the screen shots of the an example cell (0 4) The first one does the rendering correctly (this is when I use let to a assing a subscription, line of code 1 in my first screenshot) The second one doesnt render any image at all and it's the one where I use a function to refer to the subscription :piece (line of code 11) I see they are different but I can't figure out why the second case is not rendering
Hard to say from screenshtos. One thing for sure, I'd be removing the "bad" subscription. Don't leave that around. Its the wrong way to be doing it, and sufficiently so that it could be causing its own problems (although I'm not sure off hand what they might be) And you just don't want that all that extra trace getting mixed in. Confusing. And refresh the page to give yourself a fresh start
Everything you have done appears correct, which means there's something else wrong. I think. So check you other assumptions with some prints
You have clj-devtools
installed? ... so you get nice console log?
If not, see the explanations at the re-frame-template
README
I've got my brain in a twist thinking about possible race conditions in Re-frame and if anyone could help me I'd very much appreciate it.
With reg-event-fx
, there's no control over the order of effects. From the [docs](http://day8.github.io/re-frame/Effects/#order-of-effects), "TheĀ `:db`Ā side effect might happen beforeĀ `:dispatch`, or not. You can't rely on it."
How do you deal with the race conditions that this can bring up? For instance,
- :event-1
updates db
and dispatches :event-2
- :event-2
expects to have the latest version of db
, but actually you can't guarantee that, because you don't know whether the db
update happened before or after the dispatch of :event-2
I'm thinking that the way to deal with this is to pass the updated db
(or whatever part of it :event-2
needs) as a value in the dispatch of :event-2
. Is that how you'd do it?
But if I use the "pass db as value" workaround, then I can't use the [re-frame-async-flow-fx](https://github.com/day8/re-frame-async-flow-fx) library (which looks awesome!), because there's no way for one event to pass a value to the next event in the flow.
Can someone please enlighten me about how you deal with this? I have a feeling there's probably a simple solution staring me in the face that I somehow can't see.
If I'm not mistaken the non-guarantee on the order refers to the effects as returned by an effect handler. Ie. in your example, there is no guarantee that the db will get updated before queueing :event-2
But :event-2
handler will be executed after the execution of the :event-1
handler.
So, in the :event-2
handler you will always get the db with the updates from the previous handler.
Do not confuse event dispatching (ie. queueing) with event handling.
@jtlocsei ^^^ this is the key bit on information. When you dispatch, the event is queued for later processing. Soon, but not now.
@ggiraldez Do you mean that, no matter how long the execution of :event1
handler will take, reframe will wait for that execution to finish before running :event-2
handler?
Yes
The browser is a single threaded environment
I think I get it. Async doesnt mean parallel execution
Yes, exactly. One event starts Async. One event when it ends (resolves)
Thanks so much for clearing this up for me. Sounds like I can always rely on event 2 having the latest db. @ggiraldez you're right, I hadn't made a mental distinction between dispatching and handling. So, even if event 2 is dispatched before the event 1 db update, the event 2 handling will occur after the event 1 db update.