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

[Bug] 2.3.2 broke `observes` modifier #481

Closed esbanarango closed 1 year ago

esbanarango commented 1 year ago

🐞 Bug description

With the latest version of ember-concurrency the observes modifier stopped working.

import Model, { attr } from '@ember-data/model';
import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';

export default class Parking extends Model {
  @service store;

  @attr('array', { defaultValue: () => [] }) carIds;

  // This tasks should perform everytime `cardIds` changes.
  @task({
    observes: 'carIds.[]',
    drop: true,
  })
  *loadCarsTask() {
    // ...
  }
}
import Component from '@glimmer/component';
import { action, set } from '@ember/object';

export default class ParkingBox extends Component {
  @action
  onCarChange(cars) {
    const { parking } = this.args;
    const cardIds = cars.map(({ id }) => parseInt(id));

    set(parking, 'cardIds', cardIds);
  }
}

πŸ˜• Actual Behavior

loadCarsTask isn't performing when carIds changes.

πŸ€” Expected Behavior

loadCarsTask should perform everytime cardIds changes.

🌍 Environment

machty commented 1 year ago

@esbanarango did you also bump ember-source when you upgraded ember-concurrency? Asking because observers are going to be less and less supported until they're finally removed (and i'm kinda surprised they're still working in 4.6.0)

esbanarango commented 1 year ago

@machty We didn't bump those two together. observes functionality was working with:

ember-concurrency 2.2.1 ember-source 4.6.0 ember-data 4.2.0

machty commented 1 year ago

@esbanarango did you get rid of any references to ember-concurrency-decorators or any other relevant details?

esbanarango commented 1 year ago

Yeah, no usage of ember-concurrency-decorators at all.

robclancy commented 1 year ago

Seems like on: 'init' isn't working either (always felt dirty using it anyway, just being lazy). Downgrading to find version where it does work until we update everything to the new syntax.

Edit: 2.2.1 works

buschtoens commented 1 year ago

I can confirm the { on: 'init' } bug as well. Fortunately we were only using this in a single service, which we fixed by calling .perform() in the init() hook.

machty commented 1 year ago

I think it makes sense to mark this as wontfix, not out of laziness, but because Ember is heading in a different direction.

The technical reason these broke is that the new API is assigning a property at object initialization time, whereas the previous approaches manipulate the prototype (a requirement for event-based / observer stuff to work). There are probably ways to fix these APIs, but observers are already deprecated and with on init you can just put the perform in the constructor.

Happy to hear feedback on this but otherwise we're probably not gonna fix this.

esbanarango commented 1 year ago

@machty, Agreed on moving forward with Ember's direction. But this breaking change should probably be added in a major release.

machty commented 1 year ago

@esbanarango ohh... I apologize; to clarify, we shouldn't support observes in the new API, but I agree we should fix whatever broke about the old API. I'll take a closer look shortly.

machty commented 1 year ago

Fixed in v2.3.4

esbanarango commented 1 year ago

@machty this is still failing if we use the new "syntax":

Fails

// Won't perform when `cardIds` changes
loadCarsTask = task(
  {
    observes: 'carIds.[]',
    drop: true,
  },
  async () => {

  }
)

Works fine

  @task({
    observes: 'carIds.[]',
    drop: true,
  })
  *loadCarsTask() {
    // ...
  }

This's maybe fine for now, but worth mentioning.

machty commented 1 year ago

@esbanarango Yes, I think it is probably not a good idea for us to try and fix this for the new API as it would add further complexity to the EC codebase to accommodate a deprecated pattern.

AmilKey commented 5 months ago

@machty it is possible to add information on the new syntax about these events on: "init", on: "didInserElement", observes: "", because I spent a lot of time trying to figure out why it stopped working after upgrading to a new version