Seed: Is there a canonical way to block navigation to warn about unsaved changes?

Created on 20 May 2020  路  3Comments  路  Source: seed-rs/seed

Hi there. I'm relatively new to Seed, but have been having a great time so far.

I'm trying to add a feature to my Seed app that warns you if you're about to navigate away from a page and lose work that you haven't saved yet. Is there a way to intercept the url changing event and block it?

Looking at the docs, I came across the UrlRequested message. I expected something like this to work, but url_request.handled_and_prevent_refresh() doesn't seem to prevent the default behaviour of navigating to the requested page.

fn init(orders: &mut impl Orders<Msg>) -> PageModel {
    let url_request_handle = orders.subscribe_with_handle(Msg::UrlRequested);
    PageModel {
        url_request_handle
    }
}

enum Msg {
    UrlRequested(subs::UrlRequested),
}

pub fn update(
    msg: Msg,
    model: &mut PageModel,
    orders: &mut impl Orders<Msg>,
) {
    Msg::UrlRequested(subs::UrlRequested(url, url_request)) => {
        let unsaved_changes: bool = model.has_unsaved_changed();
        if unsaved_changes {
            model.show_the_are_you_sure_modal();
            url_request.handled_and_prevent_refresh();
        }
    }
}

Am I on completely the wrong path? I've tried digging into the Seed code to understand why this doesn't do what I expect, and I suspect the problem is that orders.subscribe doesn't let me set the priority of my subscription to ensure that it happens before the routing engine.

bug

Most helpful comment

Hi @MartinKavik. Thank you so much for jumping on this. I've played with your example and that's exactly what I was after.

All 3 comments

@JWorthe Congratulations, you found two Seed bugs 馃憤

  1. I wrote a function to setup low priority for system handlers, but forgot to integrate it.
  2. It still won't work after fixed (1.) because all subscribe handlers are invoked before the generated messages are processed by your update function (in other words - all handlers are called and collected into message queue). It was ok when we expected that all handlers are almost without side-effects and return messaged, but that's no longer true.

Working on it.

@JWorthe https://github.com/seed-rs/seed/pull/460 should resolve it - please test it if you have time.
I've also added new example unsaved_changes (you can run it from the root with cargo make start unsaved_changes). There there are two modal dialogs - browser's one (when user wants to go to external address); and confirm invoked from the app (when user wants to change page within the website).

Hi @MartinKavik. Thank you so much for jumping on this. I've played with your example and that's exactly what I was after.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MartinKavik picture MartinKavik  路  4Comments

TatriX picture TatriX  路  4Comments

Type1J picture Type1J  路  6Comments

bgourlie picture bgourlie  路  4Comments

MartinKavik picture MartinKavik  路  6Comments