quasarframework / quasar

Quasar Framework - Build high-performance VueJS user interfaces in record time
https://quasar.dev
MIT License
25.5k stars 3.45k forks source link

Notify causing appContext to be null #14917

Closed timsayshey closed 1 year ago

timsayshey commented 1 year ago

What happened?

I am using Vite and Quasar. And when I add Notify to the plugins, I get:

runtime-core.esm-bundler.js:218 Uncaught TypeError: Cannot read properties of null (reading 'appContext')
    at setup (defineCustomElementWithStyles.ts:31:26)

Reproduction URL

How to reproduce?

  1. Open repdroduction link
  2. Open dev console and you'll see the error.

Flavour

Vite Plugin (@quasar/vite-plugin)

Platforms/Browsers

Chrome

yusufkandemir commented 1 year ago

We've already resolved this in our community Discord server.

getCurrentInstance() needs to be called and saved into a variable before the createApp() call, probably because it affects the underlying active current instance. To make it clear, this is not necessarily related to Quasar. Notify installation uses a createApp call too. To ensure everything works, even if you are not using Notify, you should be saving the instance first.

import { defineCustomElement as VueDefineCustomElement, h, createApp, getCurrentInstance } from 'vue';
import { createPinia } from 'pinia';
import quasarIconSet from 'quasar/icon-set/material-icons-outlined';
import { Quasar, Dialog, Notify } from 'quasar';

export const defineCustomElement = (component: any, props: any) => {
  return VueDefineCustomElement({
    styles: [],
    render: () => h(component, props),
    setup() {
      const inst = getCurrentInstance();

      const pinia = createPinia();
      const app = createApp(undefined as any, props);

      // install plugins

      app.use(pinia);

      app.use(Quasar, {
        plugins: {
          Dialog,
          Notify,
        },
        iconSet: quasarIconSet,
        config: {
          extras: ['material-icons'],
        },
      });

      // @ts-ignore
      Object.assign(inst.appContext, app._context);
      // @ts-ignore
      Object.assign(inst.provides, app._context.provides);
    },
  });
};