Support for "detour" routes
mrbrahman opened this issue · 2 comments
In almost all systems where login is needed, and which supports sharing of links, say when a link like http://abc.com/#/about
is shared, if the user has not already logged in, the system prompts for login, and upon successful login takes the user directly to the about
view.
I am trying to implement something similar with Navigo, but am stuck. While Navigo does have Hooks, it seems there is no way to take a "detour" (i.e. first login, and then actual requested page).
Here's my made up example.
<div id="app"></div>
<script src="https://unpkg.com/navigo"></script>
<script>
const router = new Navigo('/', {hash: true});
const app = document.getElementById('app');
let loggedIn = false;
router.on('/login', function(){
console.log('**** in login');
app.innerHTML = `
<h1>Login</h1>
<input type=button id="submit" value="Click to login"></input>
`
document.getElementById('submit').addEventListener('click', ()=>{
loggedIn=true;
alert('you are now logged in!');
router.navigate('/home'); // would be nice to navigate to the actual view the user wanted
})
});
router.hooks({
before(done, match){
console.log('check if logged in');
if(loggedIn){
done()
} else {
console.log('need to login');
done(false);
router.navigate('/login'); // take a detour
}
}
});
router.on('/home', ()=>{
console.log('in home');
app.innerText = "In home"
});
router.on('/about', function(){
console.log('in about');
app.innerText = "In about"
});
router.on('/photos', function(){
console.log('in photos');
app.innerText = "In photos"
});
router.on('/videos', function(){
console.log('in videos');
app.innerText = "In videos"
});
router.on('/logout', function(){
console.log('in logout');
loggedIn = false;
app.innerText = "Logged out"
});
router.on('/', function(){
console.log('in /');
router.navigate('/home')
});
router.resolve();
</script>
In the example above, upon successful login, the user is always directed to /home
as that is hardcoded. It would be nice if the user is directed to whichever view/page was in the original link. And if there was none (i.e. the user wants to hit the home page), then redirect appropriately.
Thanks for your consideration.
I did manage to do a hacky, dirty workaround - by capturing the done
before it is called and then, call it later when needed. See next()
in the code below.
<div id="app"></div>
<script src="https://unpkg.com/navigo"></script>
<script>
const router = new Navigo('/', {hash: true});
const app = document.getElementById('app');
let loggedIn = false;
var next;
router.on('/login', function(){
console.log('**** in login');
// console.log(next);
app.innerHTML = `
<h1>Login</h1>
<input type=button id="submit" value="Click to login"></input>
`
document.getElementById('submit').addEventListener('click', ()=>{
loggedIn=true;
alert('you are now logged in!');
if(next){
next() // 2. call here
} else {
router.navigate('/home');
}
})
});
router.hooks({
before(done, match){
console.log('check if logged in');
if(loggedIn){
done()
} else {
console.log('need to login');
next = done; // 1. capture here
done(false);
router.navigate('/login');
}
}
});
router.on('/home', ()=>{
console.log('in home');
app.innerText = "In home"
});
router.on('/about', function(){
console.log('in about');
app.innerText = "In about"
});
router.on('/photos', function(){
console.log('in photos');
app.innerText = "In photos"
});
router.on('/videos', function(){
console.log('in videos');
app.innerText = "In videos"
});
router.on('/logout', function(){
console.log('in logout');
loggedIn = false;
app.innerText = "Logged out"
});
router.on('/', function(){
console.log('in /');
router.navigate('/home')
});
router.resolve();
// router.navigate('/photos');
</script>
However, with this the URL is not changed upon successful login. For e.g.
Would love to see a cleaner solution!
@mrbrahman A common approach is to store the URL in localStorage/sessionStorage before redirecting to /login
. Then after the user logs in you check localStorage to see if there's a URL there. If there is a URL, then you redirect to it, otherwise redirect to /home
.