Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel route using Sammy.js without affecting history

I want to intercept all route changes with Sammy to first check if there is a pending action. I have done this using the sammy.before API and I return false to cancel the route. This keeps the user on the 'page' but it still changes the hash in the browsers address bar and adds the route to the browsers' history. If I cancel the route, I dont want it in the address bar nor history, but instead I expect the address to stay the same.

Currently, to get around this I can either call window.history.back (yuk) to go back to the original spot in the history or sammy.redirect. Both of which are less than ideal.

Is there a way to make sammy truly cancel the route so it stays on the current route/page, leaves the address bar as is, and does not add to the history?

If not, is there another routing library that will do this?

sammy.before(/.*/, function () {
    // Can cancel the route if this returns false
    var response = routeMediator.canLeave();

if (!isRedirecting && !response.val) {
    isRedirecting = true;
    // Keep hash url the same in address bar
    window.history.back();
    //this.redirect('#/SpecificPreviousPage'); 
}
else {
    isRedirecting = false;
}
return response.val;
});
like image 886
John Papa Avatar asked Jun 05 '12 12:06

John Papa


2 Answers

In case someone else hits this, here is where I ended up. I decided to use the context.setLocation feature of sammy to handle resetting the route.

sammy.before(/.*/, function () {
    // Can cancel the route if this returns false
    var
        context = this,
        response = routeMediator.canLeave();

    if (!isRedirecting && !response.val) {
        isRedirecting = true;
        toastr.warning(response.message); // toastr displays the message
        // Keep hash url the same in address bar
        context.app.setLocation(currentHash);
    }
    else {
        isRedirecting = false;
        currentHash = context.app.getLocation();
    }
    return response.val;
});
like image 52
John Papa Avatar answered Sep 17 '22 17:09

John Papa


When using the code provided within the question and answer you have to notice that the route you cancelled will also be blocked for all future calls, routeMediator.canLeave will not be evaluated again. Calling a route twice and cancelling it depending on current state is not possible with this.

like image 26
Björn Peter Avatar answered Sep 19 '22 17:09

Björn Peter