fulcro

Book: http://book.fulcrologic.com, Community Resources: https://fulcro-community.github.io/, RAD book at http://book.fulcrologic.com/RAD.html
Helins 2020-11-18T12:31:53.202600Z

Very weird behavior. On pointerDown , a component transacts and re-renders itself under some condition. When the re-render happens, no click event is triggered (not its own, not from any of its children components (they don't even re-render)), but pointerUp events are all triggered as expected. Logging looks like this: pointerDown -> render -> pointerUp -> click not triggered I've already spent a few hours on this and unless I am doing something terribly wrong, it almost looks like a bug.

Helins 2020-11-19T08:02:32.224400Z

@jatkin Right, good lead but it doesn't seem to be the issue. The weirdness would remain anyways since then it would be expected that onPointerUp or onMouseUp would bizarrely not be fired either. @cjmurphy I see what you mean but lambdas in children are created solely based on their query, they don't need anything from the parent. The plot thickens.

cjmurphy 2020-11-19T08:08:04.224600Z

Still good to turn the brain off and always transact 'anything that might be triggered at the child level but apply to all children' from the parent. Good to do that regardless of any theory. Your problem is related to 're-ordering children'.

cjmurphy 2020-11-18T14:45:38.202700Z

Can 'under some condition' be done in a mutation? So both "up" and "down" both simply call a mutation.

Helins 2020-11-18T15:55:11.204100Z

Ok so I think I have slightly narrowed it down. It is not exactly the rendering after `down` that seems to be the problem. It is the mutation itself (any other one does not cause this problem). The component in question is generated from a vector of such components. What the down mutation does is ensures that it becomes last in the vector so it is rendered last. This problem happens only when the reordering happens (my 'condition', if not last, make it so). Yes, :keyis properly used as it should. It is as if reordering children on down cancels all immediate click events in those children. What is really puzzling is that immediate up events trigger just fine, proving that a click indeed happened.

cjmurphy 2020-11-18T16:13:35.204500Z

I'm afraid I don't know anything about 'generating a component from a vector of components'. To me defsc components are static things, composed together using get-query. I know you can have dynamic queries but I've never needed that feature.

Helins 2020-11-18T16:24:53.204700Z

My bad, it was just a poor way of saying that a parent component joins on a list of those components. In other words, when a mutation reorders that list via down on a child, click is mysteriously not fired, but up is. When the mutation does not reorder the list, then the expected happens : down -> up -> click

cjmurphy 2020-11-18T16:55:12.204900Z

To understand my own code better I have two functions called get-query1 and get-query* , but they are both just get-query. You mean get-query* , which ends up being a vector of idents in app state. And your mutation is re-ordering these idents within the vector.

1👍
cjmurphy 2020-11-18T16:58:37.205100Z

Also I can't get my head around what 'click' is. You have an up button and a down button that fire their respective mutations. It sounds like you are expecting a mutation to fire a click. The only thing that mutations usually 'fire' are st->st functions.

Helins 2020-11-18T17:12:19.205400Z

onClick which is fired after onPointerDown and onPointerUp (supposing all three are being used)

cjmurphy 2020-11-18T17:16:37.205600Z

I would have click as a st->st function then. Have onPointerDown and onPointerUp each call one mutation. user event -> mutation -> st->st function.

Helins 2020-11-18T17:18:30.205800Z

st -> st ?

cjmurphy 2020-11-18T17:18:58.206Z

app state in and app state out. I'll find it in the docs...

cjmurphy 2020-11-18T17:19:29.206200Z

They are functions that end in *, by convention.

cjmurphy 2020-11-18T17:20:44.206400Z

cjmurphy 2020-11-18T17:20:49.206800Z

Just search for * in the book

Helins 2020-11-18T17:29:46.207Z

Right, but the point of those onClick events is that its the standard thing to do. It has defined behavior. I am experimenting and yes, there is something weird about reordering children at onPointerDown or onMouseDown which prevents onClick events from firing.

Helins 2020-11-18T17:40:08.214900Z

My previous post seems to be a general problem so I'll try to reword it in general terms. A parent joins on a list of children. Each child registers a onMouseDown, a onMouseUp and an onClick event. A click on a child will fire those events in that order, as expected. BUT. In the case where onMouseDown reorders that list of children via a mutation, inducing a re-render before other events are processed, onClick is mysteriously NOT fired. However, onMouseUp fires as expected. This is weird because the definition of a click is exactly that, mouse or pointer going down and up on the same element. Furthermore, the dom elements don't even move (position: absolute). Nothing mysteriously unmounts/remounts. Re-rendering right after onMouseDown and before other events is not the problem. Reordering the list is. Same happens with onPointerDown and onPointerUp. Children are properly keyed, React does not complain.

2020-11-19T08:51:35.224900Z

all sounds very frustrating! did you try to use a ref and see if it changes somehow? Do you do anything to the event in the onMouseUp? E.g. preventDefault/stopPropagation?

Helins 2020-11-20T08:02:54.240400Z

Indeed it is! The ref does not seem to change and I am 100% positive there is no preventDefault or stopPropagation...

2020-11-23T02:50:38.267500Z

happens across all browsers? I guess it sounds like a react/DOM bug.

cjmurphy 2020-11-18T17:40:36.215Z

Oh right dom events. Should be possible to determine one event for one user operation. onClick means mouse has been pressed and released. Funny to have events for both onMouseDown and onClick. I'd want to avoid getting into that situation in the first place 😜

Helins 2020-11-18T17:42:02.215200Z

After some experimentation, I have rephrased the problem in my last post. Seems to be a general one. Hopefully it is more understandable.

cjmurphy 2020-11-18T17:43:39.215400Z

Can you stick to either Pointer or Mouse events and not combine them? I'd never heard of the Pointer events till now.

Helins 2020-11-18T17:46:28.215600Z

Unfortunately it doesn't change anything

cjmurphy 2020-11-18T17:48:05.215800Z

onClick doesn't happen when you do something in mouse down. Is that the problem?

cjmurphy 2020-11-18T17:48:25.216Z

onMouseDown

cjmurphy 2020-11-18T17:49:07.216200Z

And you can't avoid needing to use onClick?

Helins 2020-11-18T17:51:04.216400Z

It would mean emulating onClick in a lot of places which would only show how shitty, truly shitty, web programming is 😛

cjmurphy 2020-11-18T17:51:27.216600Z

If you are doing something in onMouseDown and something else in onMouseUp, then there is no need to have onClick. Whatever you are doing in onClick can be done in onMouseUp.

cjmurphy 2020-11-18T17:54:03.216800Z

Not so much a Fulcro problem but an event bubbling (whatever) problem.

Helins 2020-11-18T17:55:30.217Z

Might be a Fulcro problem maybe due to the mutation system? But could just as well be a problem with React

cjmurphy 2020-11-18T17:56:24.217300Z

Can you get the same behaviour with just printing messages, not doing any transacts at all?

Helins 2020-11-18T17:57:57.217500Z

Nope, my last post explains this better (I hope)

cjmurphy 2020-11-18T18:09:12.218Z

But in practical terms onClick can always be avoided if you use onMouseUp when only need 'click' functionality, and both onMouseUp and onMouseDown when doing something more involved that needs them both.

Helins 2020-11-18T18:14:05.218300Z

Yep, but using onMouseUp instead of a proper click can sometimes result in poor UI behavior. I'll hack something else meanwhile. Heck, the DOM is just one big hack anyway...

cjmurphy 2020-11-18T18:19:25.218500Z

Can you have the function that accepts the event (for onMouseDown) be passed in from the parent? So when (transact this ...) , the this is that of the parent?

cjmurphy 2020-11-18T18:21:40.218700Z

https://book.fulcrologic.com/#_the_correct_way

cjmurphy 2020-11-18T18:23:05.218900Z

Any mutation on children should always be transacted from the parent.

JAtkins 2020-11-18T19:00:01.219400Z

I'm really reaching here, but could this be related? https://book.fulcrologic.com#_callbacks_causing_over_rendering

Helins 2020-11-18T19:10:13.219600Z

Unfortunately no, those children don't actually need anything from the parent, their query suffice. The parent is a singleton easy to find.

JAtkins 2020-11-18T19:12:01.219800Z

I don't think they are the same... If you have component A, and A re-renders to the dom, and A includes lambdas, those lambdas could be changing out of under you b/c they don't compare =. Not sure if that would change anything though, because the behavior of both lambdas should* be the same.

cjmurphy 2020-11-18T19:18:14.220Z

@adam678 Are you using computed to bring any functions that call mutations that affect many children in from the parent? I want to rule that out as an issue.