Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for "detour" routes #317

Open
mrbrahman opened this issue Dec 11, 2022 · 2 comments
Open

Support for "detour" routes #317

mrbrahman opened this issue Dec 11, 2022 · 2 comments

Comments

@mrbrahman
Copy link

mrbrahman commented Dec 11, 2022

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.

@mrbrahman
Copy link
Author

mrbrahman commented Dec 11, 2022

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.

Screen Shot 2022-12-11 at 12 00 09 AM

Would love to see a cleaner solution!

@waynebaylor
Copy link

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants