Async Data and Autotracking in Ember Octane

Been there. :joy: I spoke with @pzuraq about this yesterday evening, and the problem is that Store.query uses Ember.get in a way that basically auto-tracks its own state when it’s created. Apparently other Ember Data methods used to have the same issue. The trick here is to do a lightweight form of caching to avoid recomputing unnecessarily. The reason your version with @computed works is because @computed both observes and caches any updates to its dependent keys. You can get the same effect yourself (and with much better performance) by caching yourself.

You can do that manually, like this:

import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
import { load } from 'my-app/helpers/load';

export default class PeopleComponent extends Component {
  @service('store') store;

  _previousId;
  _previousData;

  get people() {
    if (this._previousId !== this.args.id) {
      let promise = this.store.query('person', { filter: { id: ids } }).then((result) => {
        data.resolve(result.toArray());
      });

      this._previousId = this.args.id;
      this._previousData = load(promise);
    }

    return this.#previousData;
  }
}

Or you can use the polyfill for the proposed @cached decorator:

import Component from '@glimmer/component';
import { cached } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { load } from 'my-app/helpers/load';

export default class PeopleComponent extends Component {
  @service('store') store;

  @cached
  get people() {
    let promise = this.store.query('person', { filter: { id: ids } }).then((result) => {
      data.resolve(result.toArray());
    });

    return load(promise);
  }
}