Open mdcarreira opened 2 years ago
Hey @mdcarreira!
I can see how you want to access this
if you're coming from Ember. But in the setup()
function this
is undefined as you see in the useAsyncTask()
. So there's no way to fix this for vue-concurrency
it's rather a Vue Composition API issue.
It's probably WAI that this
is undefined. With composition API you should be fine with
setup()
function and then perhaps passed inside the template from thereThere should be no need to access the component instance, unless you use the Option API. vue-concurrency kind of requires you to go all in on Composition API, so I advise to read up on it more.
Hey @MartinMalinda! Thank you so much for your fast reply :)
I'm actually using the Vue Class Component library. I've seen people using the Composition API with class components, but I would prefer to continue using the class style syntax as I come from the Java world.
Can you think of a good way to go around this using the class component syntax?
Maybe I'm being overly perfectionist by not wanting to pass this
as an argument to the task... But one thing that bothers me is that this
keyword won't work in the template. If I have someTask.perform(this)
in the template, the task will receive a null
argument (??).
If I have a function in the script that performs the task with someTask.perform(this)
, the component instance is correctly passed to the task. This means that I would need to have a function just to perform the task, for every task... which is some boilerplate code that I would like to avoid.
I'm still a Vue newbie, so probably I'm making some mistake :)
I'd definitely recommend to experiment with Composition API more. It's not OOP at all, although you could do some custom OOP in the context of the setup function, but it's the most idiomatic and fleixble way to get things done in Vue for the future.
In setup function you can reuse code the most effective way, you don't have to rely on mixins and such and you can install librarie like vue-use
and quickly use many useful hooks from other people.
But for the time being, if you hold on to classes I'd try to use the SetupContext
.
export default {
setup(props, context) {
// Attributes (Non-reactive object, equivalent to $attrs)
console.log(context.attrs)
// Slots (Non-reactive object, equivalent to $slots)
console.log(context.slots)
// Emit events (Function, equivalent to $emit)
console.log(context.emit)
// Expose public properties (Function)
console.log(context.expose)
const task = useTask(function * () {
yield fetch(....);
context.emit('someEvent'); // if youre using events
props.onSuccess('some value'); // if youre using callback props
});
}
}
But one thing that bothers me is that this keyword won't work in the template. If I have someTask.perform(this) in the template, the task will receive a null argument (??).
Yeah I'm afraid you're figting the framework at this point :(
Vue is evolving away from OOP, mixins, inheritance and all that. If you really wish to keep this style (I'm not saying it's wrong in general, just not suitable in Vue), maybe vue-concurrency
is not the best option. Perhaps it would have to be forked so it's more suitable for the Options API.
Thank you @MartinMalinda for your valuable insights. You are probably right, maybe I'm better off switching to Composition API for the long term.
In the meanwhile, I wanted to try the solution you suggested, but if I export default
the object you suggest, then my class exportation will have to be named: @Component export class MyClassComponent
, and then everything breaks. What am I missing?
Thanks again for all the help :)
I've read the open issue that presents a problem similar to mine, but the discussion digressed and I couldn't find a solution to the problem. So I'm opening this new issue.
I used
ember-concurrency
when developing in Ember, and was very happy when I found that this port exists for vue.In Ember, we can use
this
to access component's state while performing a task. Unfortunately, I couldn't find a way to do the same invue-concurrency
. This would be very useful to access variables, functions, usingthis.$emit
to emit events, etc.I could implement it by making the task receive the component instance as an argument, but this feels a bit weird... Passing the component instance as argument does not feel right.
I found that there is a
useAsyncTask()
that could be defined using the arrow function and therefore would run in the same context. But for some reasonthis
isundefined
while executing the task.Is there any other way to access the component instance while a task is being executed that I missed? Or this is not possible at all?