Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with isFinished after updating to 3.15 #340

Closed
mydea opened this issue Jan 9, 2020 · 1 comment · Fixed by #341
Closed

Issue with isFinished after updating to 3.15 #340

mydea opened this issue Jan 9, 2020 · 1 comment · Fixed by #341
Assignees
Labels
bug ember-octane Issues related to use with Ember "Octane" Edition

Comments

@mydea
Copy link
Contributor

mydea commented Jan 9, 2020

Possibly related to #337, I get

Assertion Failed: You attempted to update `isFinished` on `<Task:_resolvePromise.perform()>`, but it had already been used previously in the same computation.  Attempting to update a value after using it in a computation can cause logical errors, infinite revalidation bugs, and performance issues, and is not supported.

After trying to update to 3.15 & latest ember-concurrency.

The code triggering this is a bit special, but it worked fine before:

import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { restartableTask } from 'ember-concurrency-decorators';
import { timeout } from 'ember-concurrency';

/*
 * This component takes a `promise` argument and yields an object with a `value` and a `isPending` property.
 * Note that the `value` will only change once the passed in promise is resolved!
 * This means that the last value will be used until a new value is resolved - it will not f.e. switch to `null` in between or similar.
 */
export default class AwaitPromise extends Component {
  /*
   * Arguments:
   *  - promise
   */

  @tracked _resolvedValue = undefined;
  @tracked _isRunning = false;
  @tracked _hasNeverResolved = true;
  @tracked _promise = undefined;

  get promiseData() {
    let { resolvedValue, isPending } = this;

    return {
      value: resolvedValue,
      isPending
    };
  }

  get isPending() {
    if (!this.args.promise) {
      return false;
    }

    return this._hasNeverResolved || this._isRunning;
  }

  get resolvedValue() {
    let { promise } = this.args;

    if (!promise) {
      this._resolvedValue = undefined;
      this._promise = undefined;
      return undefined;
    }

    let { _resolvedValue } = this;

    if (_resolvedValue && promise === this._promise) {
      return _resolvedValue;
    }

    if (promise !== this._promise) {
      this._resolvePromise.perform(promise);
    }

    return _resolvedValue;
  }

  @restartableTask
  *_resolvePromise(promise) {
    this._isRunning = true;

    // We have to wait a tick before setting _promise,
    // otherwise it complains that we set a property after accessing it in a getter
    yield timeout(1);

    this._promise = promise;

    this._resolvedValue = yield promise;

    yield timeout(1);

    this._hasNeverResolved = false;
    this._isRunning = false;
  }
}

Usage:

<AwaitPromise @promise={{this.promise}} as |promise|>
  {{#if promise.isLoading}}
    LOADING
  {{else}}
    {{log promise.value}}
  {{/if}}
</AwaitPromise>
@maxfierke maxfierke added bug ember-octane Issues related to use with Ember "Octane" Edition labels Jan 9, 2020
@maxfierke maxfierke self-assigned this Jan 9, 2020
@maxfierke
Copy link
Collaborator

Yep, thanks for the report. Definitely similar to #337. Looks like we'll need to more aggressively remove uses of get from @ember/object internally.

maxfierke added a commit that referenced this issue Aug 14, 2020
This test tested that certain updates to internal state didn't trigger re-render assertions.
However, firing tasks inside a getter is a side-effect not really
allowed under the autotrack system, and should not be supported.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug ember-octane Issues related to use with Ember "Octane" Edition
Projects
None yet
2 participants