machty / ember-concurrency

ember-concurrency is an Ember Addon that enables you to write concise, worry-free, cancelable, restartable, asynchronous tasks.
http://ember-concurrency.com
MIT License
691 stars 155 forks source link

Does not work with Octane #283

Closed NullVoxPopuli closed 4 years ago

NullVoxPopuli commented 5 years ago

repro repo: https://github.com/NullVoxPopuli/octane-ember-concurrency-repro

npx ember-cli new my-app -b @ember/octane-app-blueprint --yarn
cd my-app
yarn ember install ember-concurrency

with the templtae:

<div {{did-insert (perform this.myTask)}}>
  boop
</div>
import Component from '@glimmer/component';
import { task } from 'ember-concurrency';

export default class MyComponent extends Component {
  @task myTask = function*() {
    console.log('my task');
  }
}
Uncaught (in promise) Error: Assertion Failed: The first argument passed to the `perform` helper should be a Task object (without quotes); you passed undefined

and then with ember-concurrency-decorators:

Uncaught (in promise) Error: Assertion Failed: @computed can only be used on empty fields. myTask has an initial value (e.g. `myTask = someValue`)

with this preferred syntax:

  @task * myTask() {
    console.log('my task');
  }

we get a babel error:

✖ 1 problem (1 error, 0 warnings)

Build Error (broccoli-persistent-filter:Babel > [Babel: e-concurrency]) in e-concurrency/components/my-component.js

.../components/my-component.js: Unexpected token (6:19)

  4 | 
  5 | export default class MyComponent extends Component {
> 6 |   @task * myTask() {
    |                    ^
  7 |     console.log('my task');
  8 |   }
  9 | 
NullVoxPopuli commented 5 years ago

looks like this is the current way to use generators with decorators:

import Component from '@glimmer/component';
import { task } from 'ember-concurrency';

export default class MyComponent extends Component {
  @task(function*() {
    console.log('my task');
  }) myTask;
// ...
buschtoens commented 5 years ago

It is very weird that Babel chokes on @task * myTask() { ... }, as this was fixed in Babel 7. We also have tests for it here: https://github.com/machty/ember-concurrency-decorators/blob/f8b05018c2799562819311ff01f85d583d629d07/tests/unit/decorators-js-stage-2-test.js#L18-L22

I assume you are using the latest version? Can you try removing the whitespace between * and the method name?

buschtoens commented 5 years ago

Since I know that you are using TypeScript in some projects, https://github.com/machty/ember-concurrency-decorators/issues/41 will be of interest to you as well: https://github.com/machty/ember-concurrency-decorators/issues/41

NullVoxPopuli commented 5 years ago

I don't think I need ember-concurrency-decorators anymore?

but yeah, a month ago, the @task * myTask {} syntax worked, and now it doesn't. I think it may be a babel regression?

buschtoens commented 5 years ago

I don't think I need ember-concurrency-decorators anymore?

You don't need it anymore, if

but yeah, a month ago, the @task * myTask {} syntax worked, and now it doesn't. I think it may be a babel regression?

Definitely sounds like it! Might also be that this is now somehow caused by using stage 1 decorators again? 🤔

NullVoxPopuli commented 5 years ago

I think I've given up on type safety on tasks until decorators hit stage 3/4. dat : any lyfe. :( haha

wagenet commented 5 years ago

The reason @task * myTask { } doesn't work anymore is because Octane reverted to stage 1 decorators. Babel fixed this syntax but only for stage 2 decorators.

buschtoens commented 5 years ago

@wagenet How sure are you about that? I just know that it was broken for the legacy transforms in Babel 6, but I would have thought that this is a parser issue, so it should be fixed for good in Babel 7. AFAIK ember-cli is also not using the legacy transforms, but the current decorators plugin with the legacy flag enabled.

But yeah, looks like you are right. I guess we should open an issue in the Babel repo, if there is none already.

wagenet commented 5 years ago

@buschtoens I wonder if they just have a different path for legacy and didn't bother fixing the bug there? It's also possible that the spec is ambiguous for stage 1 so it technically isn't a bug?

buschtoens commented 5 years ago

@wagenet just to keep you in the loop: yes, it's a Babel bug in the stage 1 transforms. But there's already a PR to fix it waiting to be merged. More details: https://github.com/machty/ember-concurrency-decorators/issues/48

muziejus commented 4 years ago

Just adding to @NullVoxPopuli's comment, if someone were to come here looking for a solution. To append a method like restartable, one more extra set of parentheses is needed:

import Component from '@glimmer/component';
import { task } from 'ember-concurrency';

export default class MyComponent extends Component {
  @(task(function*() {
    console.log('my task');
  }).restartable())
  myTask;
// ...

Not sure where I picked this up, but hopefully it'll help someone else.

esbanarango commented 4 years ago

Just adding to @muziejus comment... if you have a task that you use in multiple places:

Image 2019-09-09 at 5 52 35 PM
NullVoxPopuli commented 4 years ago

I think we can close this now :)

kcarmonamurphy commented 3 years ago

Running a glimmer component on "ember-cli": "3.24.0", "ember-concurrency": "2.0.3" and "babel-eslint": "10.1.0" I also was not able to get the @task * myTask(argument) {} syntax working.

I had to instead use @task(function*(argument) {}) myTask

NullVoxPopuli commented 3 years ago

@kcarmonamurphy did you get an error? what is a build error a lint error?

kcarmonamurphy commented 3 years ago

@NullVoxPopuli I get the following error:

Screen Shot 2021-04-15 at 17 03 03

Code:

import Component from '@glimmer/component'
import { task } from 'ember-concurrency'

export default class MyComponent extends Component {
  ...

  @task *loadTableData(arg1, arg2) {
    this.tableData = doSomeStuff()
  }
}
maxfierke commented 3 years ago

@kcarmonamurphy It seems likely that ember-concurrency 1.x is being loaded instead of 2.x, by something else, perhaps another addon. If you're using Yarn, you can run yarn why ember-concurrency to see if another version is being loaded.