@spa-tools/core-router
Pre-Nav Confirmation
As already mentioned, the @spa-tools/core-router
package provides a way to execute pre-processing logic before navigating to a route. Another common scenario that falls into this category is prompting the user to confirm before proceeding with a navigation.
import { CoreRouter, routesFactory } from '@spa-tools/core-router';
const createMyRoutes = routesFactory();
// here we create two routes, one that is a signup form that requires
// a dirty check before navigating away form and the other is just a
// home page that does not
//
// the dirtyCheck is a 100% custom property that we will use to determine
// whether or not to ask user to confirm prior to navigating away from
// the route; it is NOT a built-in property of the route object and can be
// anything we want, which makes route flow control very flexible/powerful
const myRoutes = createMyRoutes({
homeRoute: {
dirtyCheck: false,
path: '/home',
},
signupRoute: {
dirtyCheck: true,
path: '/sign-up',
},
});
// this is just a contrived function that emulates checking whether or
// not the current route is dirty. For demonstration purposes, we don't
// really check the current route for dirty state; instead, we just
// always return true (i.e. the route is always dirty)
function fakeDirtyCheck() {
const randomDirtyState = Math.random() < 0.5 ? true : false;
return randomDirtyState;
}
// here we create a new instance of the CoreRouter class and pass in
// our routes object; we also pass in an object that implements two
// router lifecycle callbacks
const myRouter = CoreRouter.initialize(myRoutes, {
onRouteRequest: (routeRequest) => {
// if the old route has a dirtyCheck property set to `true` then
// we check to see if it is in fact dirty
const isDirty = routeRequest.oldRoute.dirtyCheck ? fakeDirtyCheck() : false;
if (isDirty) {
// since the old route is dirty, we prompt the user to confirm the
// navigation and return a promise that resolves with the answer
const answer = window.confirm('Are you sure you want to navigate away?');
return Promise.resolve(answer);
}
// this means either the old route is NOT dirty or it does not
// require a dirty check, so we return true to allow the navigation
//
// we could've also omitted the return altogether and it would have
// the same effect, but returning true is more explicit
return true;
},
onRouteChange: (routeChange) => {
// this is where we would perform any post-processing logic, which
// typically means rendering the requested route. How to do this
// ranges based on the UI framework being used, so here we simply
// log the route path to the console.
//
// If you're using React or want to create an abstraction for a
// different rendering package/framework, you should definitely
// check out the Core React Router abstraction, which has the
// rendering logic sweetly baked in.
console.log(`TODO: Render the approved route: ${routeChange.route.path}`);
},
});
myRouter.navigate(
// first, nav to the signup route, which will require a dirty check
// before being allowed to navigate away from it
myRoutes.signupRoute
// next, request to nav to home rout, which should trigger a confirmation
myRoutes.homeRoute
);