beforeLeave in Svelte

I added a beforeLeave event listener in routes.js which checks if current page is dirty or not when clicking on the back button. The problem is that if the leave event is rejected, the browser url changes even it should stay on the same page. The content of the page is not updated which is fine. I am using latest svelte with f7.

{
    path: '/Address/:id',
    component: Address,
    beforeLeave: function (routeTo, routeFrom, resolve, reject) {
      if (dirty) {
        this.app.dialog.confirm(
          'Are you sure you want to leave this page without saving data?',
          function () {
            resolve();
          },
          function () {
            reject();
          }
        );
      } else {
        resolve();
      }
    }
  },

I guess you mean native browser back button? F7 doesn’t have much control over it. You can try along with reject() to push browser history again like so:

 beforeLeave(to, from, resolve, reject) {
      const { pushStateRoot = '', pushStateSeparator } = this.params;
      history.pushState(history.state, '', pushStateRoot + pushStateSeparator + from.url);
      reject();
}

Dear Vladimir, thanks. I already tried to push back the state from before and rejecting the route change as you suggested. But the issue is still the same. When using the native browser back and forward buttons afterwards, there is no page change anymore in F7. It seams like there must be an issue with state.

The native browsers buttons back/forward become non functional after calling reject.

In my case there is another solution to prevent to use the reject feature at all. If I could call the save function on my svelte component from within routes.js beforeleave event, that would solve my issue. Is that possible somehow?

I found a workaround by setting the router.allowPageChange flag manually back to true. Please see a working solution below:

{
    path: '/Address/:id',
    component: Address,
    title: "Address Details",
    beforeLeave: async function (routeTo, routeFrom, resolve, reject) {
      let router = this.view.router;
      const { pushStateRoot = '', pushStateSeparator } = this.params;
      if (get(dirty) && !routeTo.path.startsWith("/Location")) {
        this.app.dialog.confirm(
          'Are you sure you want to leave this page without saving data?',
          function () {
            resolve();
          },
          function () {
            let url = routeFrom.url;
            history.pushState({ "view_main": { "url": url } }, '', pushStateRoot + pushStateSeparator + url);
            reject();
            router.allowPageChange = true;
          }
        );
      } else {
        resolve();
      }
    }
  },
1 Like