tobymao/snabberb

[BUG] Event handlers not working properly

sebyx07 opened this issue · 8 comments

The problem I have is with handling click events and passing a value to it. in snabbdom things are pretty straightforward

function clickHandler(number) {
  console.log("button " + number + " was clicked!");
}
h("div", [
  h("a", { on: { click: [clickHandler, 1] } }),
]);

and this the code I write in opal

click_handler = -> (_, el) do
  p "button" + Native(el).data.on.click[1] + " was clicked!")
end

h(:div, [
  h(:a, {on: click: [click_handler, 1]} )
])

As you can see, you have to go through the element to get to the value, which makes the code not really nice

can you link me to the docs in snabbdom for this? never knew you could do this

@sebyx07 so i looked into this,

are you sure snabbdom actually works with this case? i looked into the code and i have no idea how this is possible???

you can see here https://github.com/snabbdom/snabbdom/blob/master/src/modules/eventlisteners.ts#L25

function invokeHandler<N extends keyof HTMLElementEventMap>( handler: SomeListener<N> | Array<SomeListener<N>>, vnode: VNode, event?: Event ): void { if (typeof handler === "function") { // call function handler handler.call(vnode, event, vnode); } else if (typeof handler === "object") { // call multiple handlers for (let i = 0; i < handler.length; i++) { invokeHandler(handler[i], vnode, event); } } }

snabbdom loops through all the elements in the array and does handler.call(vnode, event, vnode) it never calls the handler with the second element passed in the list. can you confirm that this actually works with native javascript code?

they don't have a unit test for this, so i'm pretty sure the documentation is wrong unless i'm missing something

https://github.com/snabbdom/snabbdom/blob/master/test/unit/eventlisteners.ts

i filed a bug in snabbdom, please let me know if this actually does work in pure javascript snabbdom/snabbdom#988

I managed to fix it in a way, by wrapping the passed proc in another proc that calls the rest of list

Here is the code, I'm building a POC of writing rails w/o js and HTML. And make it reactive, similar to meteor
https://github.com/sebyx07/rails-no-js/blob/master/app/assets/javascripts/components/simple_list.js.rb

I managed to use your library from

h(:div, {class: { "class-name-1": true, }}[h(:a, "ok")])

to

div(class: "class-name") do
  a { "ok" }
end

using metaprogramming

and also to mount components in html.erb / abre, like

<div>
  <%= MyComponent(props: { x: 1}) %>
</div>

w/o actually having the components available inside the ruby on the server

i'm going to close this issue now because i think the bug is upstream, so snabbdom performs exactly the same as snabbdom

confirmed that this is outdated documentation on snabbdoms end