These are chat archives for jdubray/sam

18th
Aug 2016
Fred Daoud
@foxdonut
Aug 18 2016 13:34
@srconklin I'm late to the party, but that was an interesting issue with the onblur and onclick. As you have realized, the problem is re-rendering the link that was clicked on, as a result of processing blur/save/re-render. I was thinking of possible solutions, here is one: https://jsfiddle.net/foxdonut/940koxou/
devin ivy
@devinivy
Aug 18 2016 13:38
yes, rendering more granularly is one way to do it.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 13:39
yes but that would not be sustainable. It's not a healthy coupling .
devin ivy
@devinivy
Aug 18 2016 13:40
i don't think it's very general-purpose, though. you can see that when you click into one of the time-in/time-out inputs from the textarea you experience the same issue.
you could setTimeout(fn, 0) inside the onBlur handler.
that should let the mouse-down, mouse-up, click events clear.
you'd still have issues, for sure.
the problem is treating the dom as being immutable. setting innerHTML is just too expensive, and it destroys element references.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 13:42
the correct solution is event ordering ... it does not matter what the browser thinks the order should be.
devin ivy
@devinivy
Aug 18 2016 13:44
even if the events occurred in a different order you would have comparable issues :/
blowing away branches of your dom tree and replacing them will cause all sorts of little inconsistencies.
Fred Daoud
@foxdonut
Aug 18 2016 13:46
yes, I agree
devin ivy
@devinivy
Aug 18 2016 13:47
what i don't understand is how the argument for your state to be mutable doesn't apply to the dom. conceptually all you're trying to do is change/mutate the UI.
you can still have functional views.
e.g. react!
Fred Daoud
@foxdonut
Aug 18 2016 13:47
personally I would not implement anything of considerable size with plain HTML strings.
not sure how event ordering is a solution... no matter the order of events, if one event causes a re-render, you won't even have a chance at the second event, it won't trigger.
devin ivy
@devinivy
Aug 18 2016 13:50
the events that should be in order are your actions. the browser does not have any meaningful relationship to your application state.
i see that too @foxdonut
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:03
is there a way to read the browser event queue?
devin ivy
@devinivy
Aug 18 2016 14:06
no, but it is deterministic
conceptually, though– when you call actions should not be influenced by the implementation details of how the UI is rendered.
it seems like a setFocus action should not be necessary.
it's not really meaningful outside the context of how the UI is rendered.
devin ivy
@devinivy
Aug 18 2016 14:11
that's my impression right now, at least
Fred Daoud
@foxdonut
Aug 18 2016 14:22
I agree, @devinivy
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:30
well, sorry, an event is the occurrence of a state, if the browser can arbitrarily remove an event for whatever the reason, that is broken. The event happened, there is no reason whatsoever for that event to be subtracted from the queue
Fred Daoud
@foxdonut
Aug 18 2016 14:35
@jdubray yes but in this case, the browser did not remove an event. we pulled the rug out from under its feet.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:36
sorry, not true, the event happened, there is no reason for that event to be lost
devin ivy
@devinivy
Aug 18 2016 14:37
what event happened? the click?
Fred Daoud
@foxdonut
Aug 18 2016 14:38
This message was deleted
devin ivy
@devinivy
Aug 18 2016 14:39
the blur certainly isn't lost– it occurs, which is why the click is not allowed to complete. replacing the dom made you unable to mouse down then mouse back up on the same element.
Fred Daoud
@foxdonut
Aug 18 2016 14:39
blur happened, causing a re-render. the link on which there would have been a click, no longer exists. it would be inconsistent for the browser to emit an event on a target that does not exist.
@devinivy right, I think we are saying the same thing in different words.
devin ivy
@devinivy
Aug 18 2016 14:39
yes me too
i assume @jdubray is implying that the browser should not let you change innerhtml if a click is initiated, until it's completed?
or it should schedule that innerhtml change?
the thing is, a click on a single element might never occur. for example, if i mouse-down on one element then mouse-up on a different element.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:44
"it would be inconsistent for the browser to emit an event on a target that does not exist." but the event was emitted, the onBlur occured because of the onClick
devin ivy
@devinivy
Aug 18 2016 14:44
but i certainly did still blur.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:45
I am simply implying that the browser would work "as expected" if all events were queued up in order and it would tamper with that queue: FIFO: onClick, onBlur
devin ivy
@devinivy
Aug 18 2016 14:45
@jdubray that's the thing. blurring does not occur due to a click.
it happens directly after a mousedown
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:45
it would lead to trigger the first action (addRow) then the second (saveRow)
devin ivy
@devinivy
Aug 18 2016 14:45
because the click may not happen
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:46
ah ah
Edward Mulraney
@edmulraney
Aug 18 2016 14:47
yeah onClick is misleading
devin ivy
@devinivy
Aug 18 2016 14:47
but onClick is what you want to use to know if a link was clicked.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:48
nobody subscribed to "onMouseDown" ...
devin ivy
@devinivy
Aug 18 2016 14:48
so the way that example is being rendered just doesn't play nice.
onMouseDown occurs whether or not anyone cares about it. "if a tree falls in the woods and nobody's around, does it make a sound?"
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:49
I understand, but in the end that's what's flawed, it's like modifying the application state without a proposal, arbitrarily.
devin ivy
@devinivy
Aug 18 2016 14:49
it's going to call mousedown, blur, then if the user continues mouseup, then click.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:50
I understand, there is some logic to it, though it is not representative of how one might design the application. Imagine if SAM was starting to do things on its own, regardless of the actions you had setup?
The intent of the user was not to "mouseDown" it was to "click"
That's why I often talk about event -> intent -> action
Edward Mulraney
@edmulraney
Aug 18 2016 14:52
but i think the browser is handling the actions youve setup correctly
devin ivy
@devinivy
Aug 18 2016 14:53
but the only problem is that the application is not using the implementation of the view correctly. you're trying to say "this element i'm clicking on persists! it always exists!" but then it's being replaced all the time.
it's the job of the application to wire state and whatever's responsible for your view together (in this case the browser/DOM) in a reasonable way.
and the app's simply not being careful enough in this case.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:54
clearly not, I had created a UI where I was interested in two events: onClick onBlur and the browser added "onMouseDown" in the mix.
devin ivy
@devinivy
Aug 18 2016 14:55
the blur is going to occur before a click completes either way. that's when blur ought to occur! a click may never complete, but you certainly still blurred when you clicked down outside the textarea.
you could, for example, mouse down on one element, move the mouse, then mouse up on another.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 14:56
The browser is incorrectly assuming there is a mouseDown event when that event is in effect a click. If the browser was using SAM, it would translate the mouseDown event into a proposal and the model would react as a onClick not as a mouseDown, then have an automatic action to trigger onBlur
I'll need to think a bit more on how the state machines align, I understand your point.
devin ivy
@devinivy
Aug 18 2016 14:59
it would be amazing if our apps could be baked into the browser and we were in control of this stuff :D
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:01
IMHO, it simply means that the "save" action needs to be implemented differently to account for the browser state machine, it was erroneous to render on onBlur
we need to update the application state to provide a hook for when mouseUp or click happens
devin ivy
@devinivy
Aug 18 2016 15:03
i think so, yeah
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:03
that would be the correct implementation
devin ivy
@devinivy
Aug 18 2016 15:03
the thing i'm keying in on is that all this timing business is only so that you can blow away a portion of the DOM tree.
the events used actually make sense if you patch the dom.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:04
a change in the application state does not always equate a new state representation
devin ivy
@devinivy
Aug 18 2016 15:04
which is what you're conceptually talking about doing, "adding a row"
if i gave you two coins then you asked for three, it would be pretty strange for me to take two away then hand you three rather than just handing you one more ;D
this is the same argument for not using immutable for the model.
in the case of the DOM and the browser, considering it immutable causes real issues, especially around blurring, clicking, etc.
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:08
I see your point, I'll have to chew on that
devin ivy
@devinivy
Aug 18 2016 15:09
it's really not an issue with SAM though!
i think SAM holds up great in the browser.
it's that bloody state/view wiring!
also, i saw SAM mentioned in a redux issue yesterday!
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:10
you have a link?
devin ivy
@devinivy
Aug 18 2016 15:10
i can find it :)
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:10
it should hold, it has the structure of a state machine
it would be hard to break that structure
Edward Mulraney
@edmulraney
Aug 18 2016 15:17
@jdubray "If the browser was using SAM, it would translate the mouseDown event into a proposal and the model would react as a onClick not as a mouseDown, then have an automatic action to trigger onBlur"
you cant have a click without first having a mousedown
a "click" is simply a mousedown event followed by a mouseup event, in the same element
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:18
" None can beat redux and its ecosystem so far." (SAM, MobX...)
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:24
@edmulraney sorry, we have to think in terms of state representation to align the two state machines (browser and application). The browser state representation is what the application would react two. After each event the browser updates its state representation and we listen to it.
We would "see" a sequence of events: mouseDown, blur, mouseUp and potentially click (if we mouseUp on the link). As we talked earlier the correct implementation is not to render on blur but register a hook to render either onMouseUp or onClick (not sure how these events sort out, or if you just get one).
Scott Conklin
@srconklin
Aug 18 2016 15:27
@foxdonut yes, you have solved the issue of the blur/save/re-render issue but the redesign of the HTML outside of the view.ready() function comes at a cost of not having ALL of the HTML as a function of the model.. BUT maybe that does not matter. anyway... thanks for the suggestion. It does indeed squash the symptom of the issue
Fred Daoud
@foxdonut
Aug 18 2016 15:31
@srconklin I agree, this is not an ideal solution. It was interesting to figure out what was causing the problem, though. As was discussed previously, perhaps using something else than plain HTML strings and innerHTML would be a more viable solution.
Scott Conklin
@srconklin
Aug 18 2016 15:37

BTW: I rewrote it to not use onBlur thinking that i could avoid the issue by saving the user input on every key stroke .. but no, typing in the textarea now is not fluid as it re-renders on every keyup as well. https://jsfiddle.net/foxdonut/940koxou/

I am coming away with what @devinivy said that the best solution is to just use a DOM diffing lib to keep the dom current in just the right places..

@foxdonut yes, exactly. Posted my thoughts above before seeing your input
devin ivy
@devinivy
Aug 18 2016 15:38
or in the case of libraries like polymer, you actually describe changes to "state" directly to polymer and it doesn't even have to diff.
Scott Conklin
@srconklin
Aug 18 2016 15:39
Or that.... have on my list to look at Polymer...
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:43
@srconklin the logical way to do it, is not to render onBlur but render either onMouseUp or onClick. It's a bit painful, but that is expected to be a common pattern as we cannot assume the view state machine aligns perfectly with the application state machine.
Scott Conklin
@srconklin
Aug 18 2016 15:51
@jdubray I tried do that on onInput (see fiddle above) but it still needs work to make it smooth and usable...
why is realizing that a DOM diffing lib is not an acceptable solution?
Fred Daoud
@foxdonut
Aug 18 2016 15:55
I know this is side-stepping the issue, but if this were at my real job, I'd probably argue against saving something using onBlur. I'd have a Save button or something.
Scott Conklin
@srconklin
Aug 18 2016 15:57
@foxdonut YES, and as i have pointed out, that is exactly how the vanilla JS TODO example handles it.
This tiny app that i pulled out of a legacy app has always worked this way with Jquery manipulating the dom.... I just wanted to convert it as is to use SAM pattern
Jean-Jacques Dubray
@jdubray
Aug 18 2016 15:58
@foxdonut even if you do not link it to such an important operation, regardless it is an important point to discuss (you could do validation for instance).
Scott Conklin
@srconklin
Aug 18 2016 15:58
@jdubray disregard my last response to you. I see that you are talking about the mouseUP event not KeyUP
Jean-Jacques Dubray
@jdubray
Aug 18 2016 16:01
@srconklin the library adds a bit of complexity, it is important to have the lowest entry point (vanailla.js) and then understand why/when you need more. I don't like the idea of using stuff just because.
Scott Conklin
@srconklin
Aug 18 2016 16:14
@jdubray I understand. Then perhaps you would agree that for the sample we are discussing what @foxdonut has proposed is the best(easiest) solution
https://jsfiddle.net/foxdonut/940koxou/.
What he is doing is not unlike the solution that you proposed for the same phenomenon witnessed in the slider sample a while back; managing when to update only a portion of the DOM that needs updating.. (eg: when sliding then update the span for the retrieved slider value else view.ready() to render whole thing)
Jean-Jacques Dubray
@jdubray
Aug 18 2016 16:17
it's definitely acceptable. I have no problem with it.
Vincent Jo
@chiwoojo
Aug 18 2016 19:43
Hi JJ, I have a question about using state machines in components that will eventually use larger state machines? Good idea or no?
Currently at work we are building a component that's an audio player and it must manage it's own state
Because it is going to be used by external developers and we want to abstract logic away from them as much as possible
But also at the same time we are talking and thinking about using SAM to manage apps at the application level
@jdubray
Jean-Jacques Dubray
@jdubray
Aug 18 2016 20:11
yes parent/child SAM instances are totally ok. You just have to make provision for presenting data from the child to the parent (wiring).
you just have to make sure that the state tree is truly disjoint.
Vincent Jo
@chiwoojo
Aug 18 2016 20:15
Ok thanks, yea I thought so about the state tree, making them separate.. Joining them would be a nightmare lol
Provision you mean like hook that calls the child's SAM's action with initial values ?
Jeff Barczewski
@jeffbski
Aug 18 2016 20:27
@jdubray :+1:
Jean-Jacques Dubray
@jdubray
Aug 18 2016 20:32
yes, a child would need hooks to the parent