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>