简体   繁体   中英

Asynchronously modify value of component in Quasar

I am trying to modify the alias field when a promise is resolved. When I try to await the promise, Quasar errors out with:

[Vue warn]: Component <MainLayout>: setup function returned a promise, but no <Suspense> 
boundary was found in the parent component tree. A component with async setup() must be 
nested in a <Suspense> in order to be rendered. 

I tried wrapping everything in the <Suspense> tag including the individual spot I'm awaiting that data, but I still get this error.

I'm trying to promisify a GUN DB event that resolves a user's alias by pubkey.

<template>
  <Suspense>
    <q-layout view="lHh Lpr lFf">
      <q-header elevated>
        <q-toolbar>
          <q-btn
            flat
            dense
            round
            icon="menu"
            aria-label="Menu"
            @click="toggleLeftDrawer"
          />

          <q-toolbar-title> Quasar App </q-toolbar-title>

          <div>{{ alias }}</div>
        </q-toolbar>
      </q-header>

      <q-drawer v-model="leftDrawerOpen" show-if-above bordered>
        <q-list>
          <q-item-label header> Essential Links </q-item-label>

          <EssentialLink
            v-for="link in essentialLinks"
            :key="link.title"
            v-bind="link"
          />
        </q-list>
      </q-drawer>

      <q-page-container>
        <router-view />
      </q-page-container>
    </q-layout>
  </Suspense>
</template>

<script>
import { defineComponent, ref } from "vue";
import EssentialLink from "components/EssentialLink.vue";

import { GUN } from "boot/gun";

const gun = Gun();
const user = gun.user().recall({ sessionStorage: true });

const linksList = [
  {
    title: "Docs",
    caption: "quasar.dev",
    icon: "school",
    link: "https://quasar.dev",
  },
];

export default defineComponent({
  name: "MainLayout",

  components: {
    EssentialLink,
  },

  async setup() {
    const leftDrawerOpen = ref(false);

    let alias = "Getting alias";
    const pubkey = JSON.parse(sessionStorage.getItem("pair")).pub;

    alias = new Promise((resolve, reject) => {
      gun.user(pubkey).once((data) => resolve(data.alias));
    });

    return {
      alias,
      essentialLinks: linksList,
      leftDrawerOpen,
      toggleLeftDrawer() {
        leftDrawerOpen.value = !leftDrawerOpen.value;
      },
    };
  },
});
</script>

What is the proper way to await this data and update it in Quasar?

You could move the async operation to the mounted hook. Also, because you want alias to reactively update on the UI you should wrap it in a ref() when initializing. I've provided simplified code below showing how it can be done:

<template>
  <div>{{ alias }}</div>
</template>
<script>
import { defineComponent, ref } from "vue";

export default defineComponent({
  setup() {
    const alias = ref("Getting alias");

    return {
      alias,
    };
  },
  async mounted() {
    this.alias = await new Promise((resolve, reject) => {
      gun.user(pubkey).once((data) => resolve(data.alias));
    });
  },
});
</script>

example codesandbox

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM