GWT history with push state

262 views
Skip to first unread message

jhon tonini

unread,
Oct 3, 2020, 7:00:32 AM10/3/20
to GWT Users
Is possible to use push state in GWT history  (Es. /users, /newuser)  instead of "#" ?


Michael Conrad

unread,
Oct 3, 2020, 8:15:04 AM10/3/20
to google-we...@googlegroups.com
Have you looked at "nalu"?


Starting with version 1.1.0 Nalu supports the use of hash less URLs.

Not sure about the Domino-Kit stuff


On Sat, Oct 3, 2020 at 7:00 AM jhon tonini <crot...@gmail.com> wrote:
Is possible to use push state in GWT history  (Es. /users, /newuser)  instead of "#" ?


--
You received this message because you are subscribed to the Google Groups "GWT Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-tool...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit/a929a4a1-d268-436a-baa6-4dab200a6c40n%40googlegroups.com.

jhon tonini

unread,
Oct 4, 2020, 1:58:55 AM10/4/20
to GWT Users
Is possible implement push state in GWT  without extra libraries ?

Tino D.

unread,
Oct 4, 2020, 3:00:26 AM10/4/20
to google-we...@googlegroups.com
You need at least something to access the history api. AFAIK with elemental which is delivered with GWT you could do it (https://docs.sencha.com/gxt/4.x/javadoc/gwt-elemental-2.8.2/elemental/html/History.html).
But if you want to have something future safe you should use something that uses JsInterop. With elemental2 for example you can access History: https://javadoc.io/static/com.google.elemental2/elemental2-dom/1.0.0/elemental2/dom/History.html .
Another solution is to use domino-history:

This is a very thin wrapper for the history api which is lightweight and works with J2CL (future safe). You can check the domino-ui-demo to see how fine this works.

Thomas Broyer

unread,
Oct 5, 2020, 6:07:51 AM10/5/20
to GWT Users


On Saturday, October 3, 2020 at 1:00:32 PM UTC+2, jhon tonini wrote:
Is possible to use push state in GWT history  (Es. /users, /newuser)  instead of "#" ?

Not GWT History directly, but if you're using Places then you can use a Historian that uses pushState instead of GWT History: https://gist.github.com/tbroyer/1883821 (this is nearly 9 years old, you'll probably want to replace JSNI with JsInterop/Elemental2)

Craig Mitchell

unread,
Oct 16, 2020, 12:40:39 AM10/16/20
to GWT Users
As Tomas said, not directly with History.  It's simple JSNI though:

public static native void updateURL(String newUrl) /*-{
    $wnd.history.pushState(newUrl, "", newUrl);
}-*/;

public static native void initialise() /*-{
$wnd.onpopstate = $entry(function(e) {
@com.blah.YourClass::yourMethodThatListensForUrlChange()();
});
}-*/;

Vegegoku

unread,
Oct 19, 2020, 10:44:32 AM10/19/20
to GWT Users
JSNI is deprecated, you can use the browser state API with pushState.
You can also check domino-history which a lightweight wrapper around the pushState.

Craig Mitchell

unread,
Dec 3, 2024, 11:23:00 PM12/3/24
to GWT Users
I'm finally getting around to replacing these calls with Elemental2.

To replace the JSNI method:

public static native void initialise() /*-{
$wnd.onpopstate = $entry(function(e) {
@com.blah.YourClass::yourMethodThatListensForUrlChange()();
});
}-*/;

I would have thought it would be:

public static void initialise() {
DomGlobal.window.onpopstate.onInvoke(event -> {
// Do something
});
}

However, that doesn't compile, as onInvoke takes a @JsFunction, not a @FunctionalInterface.  So, I have to do something like this:

public static void initialise() {
DomGlobal.window.addEventListener("popstate", event -> {
// Do something
});
}

Is this correct?

Thomas Broyer

unread,
Dec 4, 2024, 4:54:27 AM12/4/24
to GWT Users
addEventListener indeed is an option (and I'd say possibly a better option), but AFAICT you could also have done:

DomGlobal.window.onpopstate = new OnpopstateFn() {
    @Override
    public onInvoke(Event event) {
        // do something
    }
});

Colin Alworth

unread,
Dec 4, 2024, 11:10:32 AM12/4/24
to GWT Users
Note that "@FunctionalInterface" is not required to express a Java interface with only one abstract method as a lambda. You can write:

DomGlobal.window.onpopstate = event -> {
    // Do something
    return null;
};

to use it as a lambda. This compiles for me with GWT 2.12.1 and Java 11.

The key is the "return null", missing in your example (and in Thomas's as well as a return type for the anon inner class). 

The return type is declared as Object, which may be an oversight in the original closure externs file, I don't see a way that an event handler can change anything by returning a different value. In JS, a missing return would implicitly return undefined, but Java requires an explicit return for non-void methods.

Thomas Broyer

unread,
Dec 4, 2024, 2:51:23 PM12/4/24
to GWT Users
On Wednesday, December 4, 2024 at 5:10:32 PM UTC+1 Colin Alworth wrote:
Note that "@FunctionalInterface" is not required to express a Java interface with only one abstract method as a lambda. You can write:

DomGlobal.window.onpopstate = event -> {
    // Do something
    return null;
};

to use it as a lambda. This compiles for me with GWT 2.12.1 and Java 11.

Does it show that I haven't written that kind of code for quite some time? 😂
(and/or rely too much on my IDE)
 
The key is the "return null", missing in your example (and in Thomas's as well as a return type for the anon inner class). 

The return type is declared as Object, which may be an oversight in the original closure externs file, I don't see a way that an event handler can change anything by returning a different value. In JS, a missing return would implicitly return undefined, but Java requires an explicit return for non-void methods.

Craig Mitchell

unread,
Dec 4, 2024, 6:14:30 PM12/4/24
to GWT Users
Thank you Thomas and Colin.  Setting onpopstate with a lambda is perfect!
Reply all
Reply to author
Forward
0 new messages