Listen to hash change event

Hi, everyone!

Does anyone knows if there is possibility to listen for hashChange DOM event. It tried to register listener on component and UI element (body) but the listener is not triggered.
Hash change event listener registration for UI element:

	UI.getCurrent()
		.getElement()
		.addEventListener("hashchange", this::handleHashChange);

In Chrome developer tools I see that there is registered listener for hashChange event (when I add listener on server side) however it is never triggered on server side. Does anyone has any idea what am I doing wrong?

Hi Olegs. The hash change event needs to be listened from the window object instead of body element. There is no reference to window from the server side Java. This is on purpose as hasn’t been needed thus far (and not needed for this, more on that later).

If you want to get the hash to the server side, two ways come to mind:

  1. I’m not 100 % this works, but you could try to add the event handler with getElemenent().executeJs(...) and server callback method, like
mainLayout.getElement().executeJs(
    "const serverCallback = element.$server.onHashChange; this.window.addEventListener('hashchange', function () {serverCallback(location.hash);}, false);"
);

and then you have in your main layout component exposed the Java method to client JS eventhandler with

@ClientCallable
public void onHashChange(String hash) {
}

Note that it cannot be UI since you really should not create a custom UI for this. Also you should make sure the JS gets executed only when the main layout is attached the first time, so on onAttach method (since you probably don’t remove the main layout ever).

  1. The same as 1) but you export the executed JS which adds the hash change listener into a JS module and call the Java method from it, similarly like shown in [this tutorial]
    (https://vaadin.com/tutorials/calling-java-from-javascript).

But, the main point for why we don’t have Java API for hash change event, is that it is supposed to be browser only feature and not sent to server side. I’d urge you to think whether you should be using something else instead of hash (more details in https://github.com/vaadin/flow/issues/2742)