PolymerElements / app-route

A modular client-side router

Home Page:https://www.polymer-project.org/1.0/articles/routing.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: How to use app-route to redirect path (i.e. upon successful sign-in)

andrewspy opened this issue · comments

What's the best way to use app-route/app-location to redirect to different path? Shall I just use window.location directly? i.e. firebase-auth code below:-

...
signIn: function() {
  this.$.auth.signInWithPopup()
    .then(function (response) {
      window.location = '/'; // XXX: Redirect upon success
//            window.history.pushState({}, null, '/');
//            window.dispatchEvent(new CustomEvent('location-changed'));
    });
},
...

I prefer to use a simple wrapper which does the check. In your iron-pages use something like

<iron-pages attr-for-selected="data-route" selected="{{route}}">
  <div data-route="home">
    <home-page></home-page>
  </div>
  <div data-route="my-area">
    <login-check user="{{user}}">
      <my-area user="{{user}}"></my-area>
    </login-check>
  </div>
</iron-pages>

And login-check is a wrapper which does:

<template>
  <template is="dom-if" if="{{exists(user)}}" restamp="true">
    <content></content>
  </template>
  <template is="dom-if" if="{{!exists(user)}}">
    <login-form on-logged-in="storeUser"></login-form>
  </template>
</template>

This makes routing composable without redirecting 😄

Shouldn't app-route provide a API for redirection? or is it not advisable to have a redirection in SPA?

I would personally advise against redirection. It was an old pattern ot MPA since these would not know what to do, but in a SPA you actually know what to do and do not want to punish a user with a redirect. It is costly for no benefit :)

I solve this issue by having two elements below <my-app> - A bit like so

<my-app>
  <my-session user="{{user}}" is-logged-in="{{isLoggedIn}}" hidden$="{{isLoggedIn}}></my-session>
  <my-pages user="{{user}}" hidden$="{{!isLoggedIn}}">
   <app-location route="{{route}}"></app-location>
  <app-route="{{route}} ...
 </my-pages
<my-app>

That way any logging in is outside of the url structure. My rationale is that the real reason for having a router is to expose urls to the user, who might use them copy and paste to someone else to access a particular part of the application. If that some else is not logged in, then I want them to be able to do that without changing the url

I understand the part on using a composable element for login, but there are instances where the web app needs to be redirected to different section/part of the app to make it more user friendly, and it would be great to have an API for that purpose. Shall this be a feature request?

You can easily switch path to a completely different url by doing the following

        window.history.pushState({}, null, '/a_new_url');
        window.dispatchEvent(new CustomEvent('location-changed'));

I generally do the above when its in a way different part of the tree, or I adjust my route.path for local changes. If I need to know the return address, I normally write it into a return query parameter.

@akc42 I am new to javascript's promise, does it mean that there is no way to access route.path inside the promise returned by signInWithPopup()?

@ack42 I managed to do the following:-

...
signIn: function() {
  this.$.auth.signInWithPopup()
    .then(function (response) {
      // Redirect upon success
      app = this.document.querySelector('my-app');
      app.set('route.path', '/');
    });
},
...

I shall close the issue. Thanks!

@TimvdLippe Your example does not work as expected. I want to wrap your example only on certain views then needs to be authenticated but even if I am not in that specific route the login-check gets executed and logs out all my views. Also since I am using the prpl pattern makes things abit more complex

Has been another other solutions. Is the polymer team gonna implement some auth-route component?

@JGSolutions The check should only check the status, but not do any logic. E.g. it should not log you out. That is logic that should be in your app component.

Given that authentication is very project-specific, I doubt it is feasible to create a specific component for that.

Ok i came up with something and paste the code in jsbin soon

Here is a quick example of code
https://jsbin.com/kiyiteqiba/edit?html,css

So this will still use the prpl pattern. And will not load the component into memory until auth is valid