adopted-ember-addons / ember-cp-validations

Ember computed property based validations

Home Page:https://adopted-ember-addons.github.io/ember-cp-validations/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Computed Validation Value Based on Cached Value Instead of Current

MuseofMoose opened this issue · comments

Since I started using ember-cp-validations, I've occasionally run into an issue similar to the one reported here:
#596

More or less, some of our computed validations can end up being "one step behind" where the validation state will be based on the previous value entered into the field, not the current value. It's not clear to me precisely what causes it but chaining .volatile() off of the computed property that drives the validation (a workaround mentioned in the linked issue) has allowed me to force them to recompute on every change and get around the problem.

With Ember 3.9's release, however, we now have a deprecation warning for using .volatile with computed properties. Given that my current workaround is going to get the axe at some point in the near future, I figured now would be a good time to bring the issue up.

For example, I have a model property named reportInterval that has the following validation:

reportInterval: [
  validator('number', {
    allowBlank: true,
    lte: or('model.computeWindow', 10),
    dependentKeys: [
      'model.computeWindow',
    ],
    message(type) {
      const thresholdValue = this.model.getWithDefault('computeWindow', 10);
      return 'Report Interval must be less than or equal to ${thresholdValue}',
    },
  }),
]

The dependentKey property, computeWindow, is nothing special. Simply a basic property on the same model. It does have its own validations but they're pretty straightforward (and have no problems).

Say I set computeWindow to 10 and reportInterval to 15. This will cause a validation message to pop up as expected:
Screen Shot 2019-04-29 at 7 21 41 PM

I then change the computeWindow value to 20 (which should make everything valid). The validation message does not go away. Amusingly, the validation message text does update:
Screen Shot 2019-04-29 at 7 28 05 PM

Next, I change the computeWindow back to 10 (an invalid value). The validation message does go away this time:
Screen Shot 2019-04-29 at 7 25 05 PM

And this is what I mean by it being "one step behind". For whatever reason, it appears the value of model.computeWindow that's being used when doing the validation is the previous value, not the current value. So when I set computeWindow to 20, it still validates against the previous value of 10. And when I then set the value back to 10, it validates against the new previous value of 20.

Workarounds:
Adding .volatile() to the computed makes everything work (though it recomputes on any change, now):
lte: or('model.computeWindow', 10).volatile()

Puzzlingly, removing the 'or' macro and simplifying the computed also fixes it:
lte: reads('model.computeWindow')

The second approach isn't ideal since I lose the validation against a default value when computeWindow isn't specified.

Looks like my issue with depended fields (date + time) with custom validator. My validate() function works properly, but computed property by model.validations.attrs.my_field.isValid (or any other) is not recomputed.

I could not find any workaround like volatile/get or something else and only dirty hack helped me - on change date I clear and fill back time field to recompute validation.

Ember 3.15
ember-cp-validations@4.0.0-beta.10

@MuseofMoose is this still an issue with the latest beta release?