[SOLVED] Login screen (separate page) persists after successful authentication

Good evening,

I have a strange situation in my F7 / Vue application where my login screen (a separate page) does not dismiss upon successfully authenticating, even though I seem to be resolving to a target component within a router async method.

The main page route is successfully intercepted by the async guard in route.js. The separate Login page presents via the resolve() function. I successfully authenticate, which causes the user and token to be placed in the Vuex store. A watcher in app.vue detects the successful login and navigates to the main page url. The async guard correctly detects the user is authenticated and attempts to resolve to the actual HomePage component.

The problem is that the Login page is never replaced with the Home page’s content, even though the effective component is correct. No errors are ever thrown in the console, which looks like the following highlights:

[HMR] Waiting for update signal from WDS...
no token
.
.
.
auth changed true
have token

Does the separate Login page need to be closed like the popup variants? Has the Login page somehow become bound to the ‘/’ route in such a way that I can no longer route to the real component?

I am new to Framework7 so I am sure that I am missing something simple. I have searched the forums, trying several different ideas encountered. It got me this far. I am just missing the last piece.

Any thoughts?

Here are the files in question…

app.vue (abreviated)

<template>
  <f7-app :params="f7params" >
    <f7-statusbar></f7-statusbar>
    <f7-view main url="/"></f7-view>
  </f7-app>
</template>
<script>
  import { mapGetters } from 'vuex'
  import { AuthService } from '@/modules/auth'

  export default {
    computed: {
      ...mapGetters(['isAuthenticated']),
    },
    watch: {
      isAuthenticated: function(val) {
        console.log('auth changed', val);
        this.$f7.views.main.router.navigate({url: '/'});
      }
    }
  }
</script>

route.js

import HomePage from '@/pages/private/HomePage.vue';
import LoginPage from '@/pages/public/LoginPage.vue';
import NotFoundPage from '@/pages/404.vue';

import store from '@/modules/store'

function securedRoute(path, component) {
  return {
    path,
    async(to, from, resolve, reject) {
      if (store.getters.isAuthenticated) {
        console.log('have token, routing to', component);
        resolve({ component: component });
      } else {
        console.log('no token', component);
        resolve({ component: LoginPage });
      }
    }
  }
}

var routes = [
  securedRoute('/', HomePage),
  {
    path: '(.*)',
    component: NotFoundPage,
  },
];

export default routes;

LoginPage.vue

<template>
  <f7-page login-screen>
    <f7-login-screen-title>{{$t('appl.title')}}</f7-login-screen-title>
    <f7-list form>
      <f7-list-input
          type="text"
          :label="$t('pages.public.login.form.fields.username.label')"
          :placeholder="$t('pages.public.login.form.fields.username.placeholder')"
          :value="username"
          @input="username = $event.target.value"
          autofocus></f7-list-input>
      <f7-list-input
          type="password"
          :label="$t('pages.public.login.form.fields.password.label')"
          :placeholder="$t('pages.public.login.form.fields.password.placeholder')"
          :value="password"
          @input="password = $event.target.value"></f7-list-input>
    </f7-list>
    <f7-list>
      <f7-list-button 
          :title="$t('pages.public.login.form.buttons.signin')"
          @click="login"></f7-list-button>
        <f7-block-footer>{{$t('pages.public.login.footer')}}</f7-block-footer>
    </f7-list>
  </f7-page>
</template>

<script>
import { AuthService } from '@/modules/auth'

export default {
  data() {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login() {
      AuthService.login(this.username, this.password).then(auth => {
      }).catch(error => {
        console.log('error', error);
      })
    }
  }
}
</script>

It can happen, because it has same URL / so router doesn’t navigate to same URL, page, just add reloadCurrent: true:

this.$f7.views.main.router.navigate('/', { reloadCurrent: true });
1 Like

Thanks so much! That worked beautifully! I was SO focused on the routing guard logic that I did not think to apply that flag to the navigation in app.vue.

BTW, I really like Framework7 so far. I have been experimenting with it as an alternative to Vuetify.

Hi Vladimir,

One potential correction. this.$f7.views.main should be this.$f7.views.current.

Correct me if I’m wrong. Programatically, the main view might NOT be the current view. So safely, I am always call this.$f7.views.current.

Well it depends on your app, and views/modals you use. If you have more than one then yes :wink: