In Vaadin framework, how can I get the client time zone to use in rendering the very first page displayed

Viewed 331

The latest recommended way to get the timezone from the client is via...

UI.getCurrent().getPage().retrieveExtendedClientDetails(extendedClientDetails -> {
        extendedClientDetails.getRawTimezoneOffset();
        extendedClientDetails.getTimezoneOffset();
});

However this method is not synchronous the first time it is called. Which means we can't use the timezone information to render the first page displayed to the user.

Is there a work-around to get this information prior to rendering the first page (e.g. when the session is initialized)? Or can I somehow indicate that I want vaadin to grab that information when the session is first created?

2 Answers

There's no way of doing that since Vaadin needs a chance to run JavaScript in the browser to find out that information. As a workaround, you can implement any view that depends on the information to postpone rendering its actual contents until the information is available.

Your view could thus be something along these lines:

@Route
public class MyView extends VerticalLayout {
  public MyView() {
    UI.getCurrent().getPage().retrieveExtendedClientDetails(details -> {
      add(new Text("Your time zone offset: " + details.getTimezoneOffset()));
    });
  }
}

This will initially just show an empty shell if the details are not available. It should typically just last a moment until the extended details have been fetched so the user might not even notice the delay. If you want to make it more explicit, then you can show some temporary placeholder content such as an indeterminate progress bar in the meantime.

UI.getCurrent().getPage().retrieveExtendedClientDetails(details -> {
  removeAll(); // Remove spinner if it happened to be there
  add(new Text("Your time zone offset: " + details.getTimezoneOffset()));
});
if (getComponentCount() == 0) {
  // We only get here if the Text component wasn't added immediately
  ProgressBar spinner = new ProgressBar();
  spinner.setIndeterminate(true);
  add(spinner);
}

I believe the answer is no. The browser doesn't supply that information on the initial request; you can only execute JS after the first response has returned to the browser.

Related