I've been grappling with my Vue 3 / TypeScript app and the vue-concurrency library.
Everything is nearly in place, but configuring a Task Creator to accept arguments has proven to be quite challenging.
Following the Task Creators pattern outlined in the documentation, here's an example:
src/composables/tasks.ts
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-return */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { timeout, useTask } from 'vue-concurrency';
export const useReturnTextTask = (text: string) => {
return useTask(function* () {
// Simulate an API call that takes a string argument and returns a string
yield timeout(1000);
return text;
});
};
Within a component, it's implemented like this:
src/components/example.vue
<template>
<input v-model="textInput" type="text" />
<button @click="handleClick">Click to Perform Task</button>
<div v-if="returnTextTask.last?.isError">
{{ returnTextTask.last?.error.message }}
</div>
<div v-else>
{{ returnTextTask.last?.value }}
</div>
</template>
<script setup lang="ts">
/* eslint-disable @typescript-eslint-no-unsafe-member-access */
/* eslint-disable @typescript-eslint-no-unsafe-assignment */
/* eslint-disable @typescript-eslint-no-unsafe-call */
import { useReturnTextTask } from 'src/composables/test';
import { ref } from 'vue';
const textInput = ref<string>();
const handleClick = async () => {
if (textInput.value) {
const returnTextTask = useReturnTextTask(textInput.value);
const returnTextInstance = returnTextTask.perform();
await returnTextInstance;
if (returnTextTask.last?.isSuccessful) {
console.log(returnTextTask.last?.value);
console.log(returnTextInstance.value);
}
}
};
</script>
The issue arises because useReturnTextTask
requires a text
argument, so I utilized it within if (textInput.value)
.
However, using it that way results in all references to returnTextTask
in the template throwing the error
Cannot find name 'returnTextTask'. ts(2304)
.
This seems to be due to the fact that returnTextTask
may not always be defined when nested inside if (textInput.value)
.
How can I resolve this challenge?
I also attempted declaring returnTextTask
outside of handleClick
, such as
let returnTextTask: Task<string, []>;
, however, this led to runtime errors as it was declared with an undefined value (TypeError: Cannot read properties of undefined (reading 'last')
).