[Solved] Strange behaviour swipeback + Async Lazy Components

Hi,
I have a strange behavior when swiping back on ios theme. I didn’t test it on md.
But after going deep in my app and swipe back my view broke. There are two pages with page-current class, and both pages are overlapping.

If needed i will do a repo to reproduce the error.
i use f7 4.0.5 + vuejs

Meanwhile here is a gif of my issue:

swipeback-f7

Here is my router.js

export default [
...
{
    path: '/novedades/',
    async (routeTo, routeFrom, resolve, reject) {
      const vueComponent = () => import('./views/News.vue')
      vueComponent().then((vc) => {
        resolve({ component: vc.default })
      })
    }
  },
  {
    path: '/news-detail/',
    async (routeTo, routeFrom, resolve, reject) {
      const vueComponent = () => import('./views/NewsDetail.vue')
      vueComponent().then((vc) => {
        resolve({ component: vc.default })
      })
    }
  }
...]

if i dont use async comp it works fine:

{
    path: '/novedades/',
    component: NewsPage
  },
  {
    path: '/news-detail/',
    component: NewsDetailPage
  },

my f7params:

f7params: {
  routes,
  touch: {
    fastClicks: true
  },
  input: {
    scrollIntoViewOnFocus: true,
    scrollIntoViewCentered: true
  },
  smartSelect: {
    pageTitle: 'Seleccione',
    sheetCloseLinkText: 'Ok'
  },
  panel: {
    swipeNoFollow: true,
    swipe: 'left'
  },
  view: {
    stackPages: false,
    removeElements: true
  },
  on: {
    init: () => {
      console.log('f7 app init')
    }
  }
}

Do you have a fiddle or live version so i can check?

will do it right now. thanks

Just notice my gif was only the first 5 sec. So i reupload the full gif.
And im workingo on the fiddle. try with codesandbox but importing the vue component async didnt work. So im looking for an alternative.

Hey bro… Have you tried setting stackpages property to true and testing again? This could be because async has trouble reloading the component Lazily… Just thinking.

1 Like

Hi @max, @nolimits4web

Just change to stacked pages and it solve my problem!
My mistake was all the heavy work that path ‘/’ had to do before importing my component.

Framework7 works flawlessly on my app, it was my codding the error!

{
  path: '/',
  async (routeTo, routeFrom, resolve, reject) {
    // Login 1
    let ComponentLoginSS = () => import('./views/login/LoginSS')
    // Login 2
    let ComponentLoginGeneric = () => import('./views/login/LoginGeneric')
    // Home page
    let ComponentHome = () => import('./views/Home')
    // Find in localstorage user credentials
    if (ValidateCredentials()) {
      // This function was generating the error.
      ValidateUser()
        .then(res => {
          if (res) {
            ComponentHome().then((vc) => {
              resolve({ component: vc.default })
            })
          } else {
            ComponentLoginSS().then((vc) => {
              resolve({ component: vc.default })
            })
          }
        })
        // eslint-disable-next-line
        .catch (err => {
          // this.$util.showMessage(this, err)
          ComponentLoginSS().then((vc) => {
            resolve({ component: vc.default })
          })
        })
    } else {
      if (getApp()) {
        ComponentLoginSS().then((vc) => {
          resolve({ component: vc.default })
        })
      } else {
        ComponentLoginGeneric().then((vc) => {
          resolve({ component: vc.default })
        })
      }
    }
  }
},

What i think is the cause of the error:

ValidateUser()
Here is the problem. before i allow to enter HOME i validate the user against the server, async. A user can loose access to the app at any time.
So f7 is waiting the server response before resolving home component, but in the meantime i continue swiping back. so that break the router.
Router history has HOME ‘/’ but it dosnt have the component YET.

If anybody has a suggestion on how to fix this, without using stacked pages it would be awesome.

1 Like

Glad you found a fix, awesome!

it troubled me at some point until @vladmir told me that stackpages property keeps components in the dom.
It was something like this:

Page1 -> async, make a request, and resolve a component Page 2-> Move on to -> Page 3. Now try to go back to Page 2, it would do the request a fresh…which was quite annoying.

With stackpages, you are telling F7 to keep pages in view with previous-page class.

Maybe Vlad has another solution, lets wait and see.

1 Like

Yes. I wanted to use stacked pages bcs all my pages have heavy data. So my intention was to remove pages from dom. Only keep current and previous. As stacked false do. To improve performance. Buy my code is beaking f7 normal behaviour.

1 Like

Oh. If you do heavy ajax calls numerously, then, loading once and keep everything in place will help performance wise. Just thinking, am not really sure it does :grinning:. Probably, @nolimits4web has another way to go about this. I had an app that’s been reliant on requests. Reworking it to F7 vue and relying on vuex has really helped a lot. I do one call at the beginning with so much data and sustain it in my store + localstorage. Then everytime i visit the pages, i listen to pageAfterIn event and do a call to update specific part of data behind the scenes. This has improved performance so much as, most parts of the app can be used offline.
But i am sure there is a better way,:wink:

1 Like