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

PaperForm throwing backtracking assertion 3.16 + #1127

Open
betocantu93 opened this issue Feb 17, 2020 · 6 comments · May be fixed by #1173
Open

PaperForm throwing backtracking assertion 3.16 + #1127

betocantu93 opened this issue Feb 17, 2020 · 6 comments · May be fixed by #1173
Labels

Comments

@betocantu93
Copy link
Contributor

Hello, trying to upgrade to 3.16.2 but got this error, starting from 3.16.0 AFAIK.

Related PR: emberjs/ember.js#18554

<PaperForm as |form|>
  {{#if form.isInvalid}}
    This form is invalid
  {{/if}}
  <form.input @onChange={{action (mut this.value)}} @value={{this.value}} @required={{true}}/>
</PaperForm>

Throws
image

@betocantu93
Copy link
Contributor Author

betocantu93 commented Feb 17, 2020

A monkey-patch or quick fix is to rewrite the isInvalid and isTouched computeds to normal props that are setted by observers using scheduleOnce.

import PaperForm from "ember-paper/components/paper-form";
import { observes } from "@ember-decorators/object";
import { scheduleOnce } from "@ember/runloop";

export default class PaperFormComponent extends PaperForm {
  isInvalid = null;
  isTouched = null;

  setProp(key) {
    this.set(key, this.get("childComponents").isAny(key));
  }

  @observes("childComponents.@each.isInvalid")
  isInvalidObserver() {
    scheduleOnce("afterRender", this, this.setProp.bind(this, "isInvalid"));
  }

 @observes("childComponents.@each.isTouched")
  isTouchedObserver() {
    scheduleOnce("afterRender", this, this.setProp.bind(this, "isTouched"));
  }
}

@miguelcobain
Copy link
Owner

This is indeed a problem.

I'd just like to point out another workaround that is just using isInvalid afterwards, and possible using flex's order or other styling to position the invalid dependent content where you need it.

<PaperForm as |form|>
  <form.input @onChange={{action (mut this.value)}} @value={{this.value}} @required={{true}}/>
  {{#if form.isInvalid}}
    This form is invalid
  {{/if}}
</PaperForm>

Not sure how to fix this the correct way since this is, by definition, something that depends on things rendered "afterwards".

@betocantu93
Copy link
Contributor Author

betocantu93 commented Feb 19, 2020

Yes, I'm not sure either how to refactor this... maybe we could ask @pzuraq for advice

@mtrunt
Copy link

mtrunt commented Feb 26, 2020

I found the same assertion error when trying to implement a similar logic to ParentMixin and ChildMixin and solved it by changing the init on the ChildMixin to didInsertElement; however this was only a 1 level deep relation (parent won't be the child of another parent).

@betocantu93
Copy link
Contributor Author

I think the init func in childMixin could have afterRender...

import { scheduleOnce } from "@ember/runloop";
export default Mixin.create({
init() {
    this._super(...arguments);
    if (this.get('parentComponent')) {
      let fn = () => {this.get('parentComponent').register(this)}
      scheduleOnce('afterRender', this, fn);
    }
  },
});

@Bartheleway
Copy link

Bartheleway commented Nov 1, 2020

Any updates on this ? For what it's worth, I think the correct way to handle all this parent/child nightmare is through events.
I will try to solve this, no promises ;)

@Bartheleway Bartheleway linked a pull request Nov 3, 2020 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants