I came across this vue-concurrency which looks like a great library for handling asyc calls.
But I'm having trouble understanding how to implement it.
Here is a simple Vue component using vue-concurrency:
<template>
<div>
<div v-if="task.isRunning">Loading...</div>
<div v-else-if="task.isError">{{ task.last?.error.message }}</div>
<div v-else>
{{ task.last?.value }}
</div>
</div>
</template>
<script setup lang="ts">
import { timeout, useTask } from 'vue-concurrency';
const task = useTask(function* () {
yield timeout(1000);
if (Math.random() < 0.5) {
// lets say the API is flaky and errors out often:
throw new Error('Ruh oh. Something went wrong.');
} else {
return 'tada';
}
});
const instance = task.perform();
// Now I try to access some of the varibles
console.log(instance.isError); // runs immediatley, always returns "false"
console.log(instance.error); // runs immediatley, always returns "null"
console.log(instance.value); // runs immediatley, always returns "null"
console.log(task.isError); // runs immediatley, always returns "false"
console.log(task.last?.isError); // runs immediatley, always returns "false"
console.log(task.last?.error); // runs immediatley, always returns "null"
console.log(task.last?.value); // runs immediatley, always returns "null"
</script>
This component makes a fake API call. Pauses for one second. Then will either throw an Error or return the "tada" string.
The current code works in the template, it shows "Loading..." and then either "tada" or the error message.
But I want to access the task and instance variables inside the script tag, and at the moment they all run immediatley without waiting for the async call to execute.
I thought I could fix this by using await task.perform()
. Doing so gives me the task.last?.value
variable. But the template stops working (becomes blank) and the error variables don't print to the console.
So how do I correctly access the state values of a vue-concurrency Task/Instance inside the script tag?