I have below two components (parent and child)
.
├── Index.vue (Parent)
└── _GetShipment.vue (Child)
In the Index.vue
I am trying to get the content of the e-mail body using Office.js's getAsync:
<script>
import Shipment from './_GetShipment.vue';
import { ref, defineComponent, Suspense } from 'vue';
export default defineComponent({
setup() {
const shipments = ref([]);
shipments.value = Office.context.mailbox.item.getRegExMatchesByName('ShipmentNumbers');
if (!shipments.value) {
Office.context.mailbox.item.body.getAsync(
"text",
function (result) {
if (result.status === Office.AsyncResultStatus.Succeeded) {
let matches = result.value.match(/S\w{3}\d{8,9}/ig);
if(matches){
shipments.value = matches;
}
}
}
);
}
return {
shipments,
}
},
components: {
Shipment
},
})
</script>
<template>
<Suspense>
<Shipment :id="shipments[0]" />
<template #fallback>
Loading...
</template>
</Suspense>
</template>
In the child component, I fetch data using the async setup
method:
<script>
import { ref } from 'vue';
export default {
props: ['id'],
async setup(props) {
const shipment = ref();
await fetch(route('getShipment', {id : props.id}))
.then(response => response.json())
.then(data => shipment.value = data);
return { shipment };
}
};
</script>
<template>
<div>
<pre>{{ JSON.stringify(shipment, null, 2) }}</pre>
</div>
</template>
When navigating to my page, Index.vue
, the Loading...
fallback message from Suspense
is being shown, and the async data from the child is also being loaded.however, the console also throws an error:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '0')
I guess this is because when Index
is loaded, the shipments
variable is not set, but will be set just after load.
If I render the child component using a v-if
, like so:
<template>
<Suspense>
<Shipment v-if="shipments" :id="shipments[0]" />
<template #fallback>
Loading...
</template>
</Suspense>
</template>
Then the fallback loading message is not being shown. How can I call an async function (getAsync()
) whilst still showing the loading message using Suspense
?
The comment from Jaromanda X put me on the right track:
not sure if
:id="shipments?.[0]"
would help
When the component is loaded, the shipments
variable is empty - as it is waiting for the async function getAsync
to finish.
Adding the code from Jaromanda X to the parent component:
<Shipment :id="shipments?.[0]" />
And then in the child component, I added this under the async setup(props)
method:
while(!props.id){
await new Promise(resolve => setTimeout(resolve, 100));
}
This got rid of the error in the log, the loading message is successfully showing until the fetch
is done.