[SOLVED] Proper use of calendar component in async routed component?

Hi there,

I have a page in a .vue component, which uses calendar (among others).
The relevant part of script section is:

import Framework7 from 'framework7'
import Calendar from 'framework7/components/calendar/calendar.js'
import Input from 'framework7/components/input/input.js'
import Popover from 'framework7/components/popover/popover.js'
import SmartSelect from 'framework7/components/smart-select/smart-select.js'

Framework7.use([Calendar, Input, Popover, SmartSelect]);

export default {

  data() {
    return {
     ....    
    }
  },


  methods: {

    onPageBeforeInit(e) {
      const self = this;
      const app = self.$f7;

      let calendar = app.calendar.create({
                inputEl: '#validityDateSelector',
                closeOnSelect: true,
                dateFormat: 'yyyy.mm.dd.',
                routableModals: false,
      });
    }
  }
}

All works fine if the component is routed the simple way like this:

...
import PageWithCalendar from './pages/page-with-calendar.vue'

...
  {
    name: 'page-with-calendar',
    path: '/page-with-calendar/',
    component: PageWithCalendar,
  },

But if I change the route to async and omit the page import, then app.calendar is undefined during the PageBeforeInit callback and the page component fails to load:

...
  {
    name: 'page-with-calendar',
    path: '/page-with-calendar/',
    async(routeTo, routeFrom, resolve, reject) {

      const vueComponent = () => import('./pages/page-with-calendar.vue');
      vueComponent().then((vc) => {
        resolve({ component: vc.default });
      });
  },
...

Seems to me as a module dependency issue (which can be resolved compile-time, but fails runtime).

I’m using the webpack4 template, with f7-vue 3.5.1.

Thanks in advance,
Bálint

.use can’t install it correctly during runtime and after F7 was initialized, it is better to lazy api http://framework7.io/docs/lazy-modules.html#modules-api or try to rework route like:

...
  {
    name: 'page-with-calendar',
    path: '/page-with-calendar/',
    async(routeTo, routeFrom, resolve, reject) {
      var app = this;
      Promise.all([
        import('framework7/components/calendar/calendar.js'),
        import('framework7/components/input/input.js'),
        ...
      ])
      .then((modules) => {
        var modulesToLoad = modules.map(module => module.default);
        return app.loadModules(modulesToLoad);
      })
      .then(() => {
        const vueComponent = () => import('./pages/page-with-calendar.vue');
        vueComponent().then((vc) => {
          resolve({ component: vc.default });
        });
      })
  },
...

Or move that logic to page component

Thanks, Vladimir!
Finally, using the lazy api seemed to me the best choice.

Bálint

1 Like

I’ve used this snippet but the console shows

TypeError: app.loadModules is not a function

I am using Vue and initializing the app through f7-app params.