Understanding what to expect from ember-changeset

Hi - I have started using ember-changeset with my app and it isn’t working the way I expected. I am wondering if there is a way to harness ember-changeset to do what I want.

Here is what I would expect from a changeset: changesets

Underlying assumptions:

  • Anything that originates from a user in any form is suspect.
  • Each source of user-supplied data needs to be validated.
  • Each source needs its own changeset and its own error list.
  • Once something is validated, it gets pushed into state.
  • The rest of the system is wired to only pay attention to validated state.
  • System state changes get delivered to all the changesets attached to it, flushing pending inputs.
  • When that happens, those fields are no longer “dirty”.
  • Consequently, the error list showing for a source should accurately reflect the error state of the mix of “clean” and “dirty” data sitting in that source’s changelist.

Instead, I find that when the state changes, the data in the changeset updates accordingly, but the error list retains all of the errors in the data that was in the changeset before the update. No errors are removed and no fields are revalidated.

Is this expected behavior? Is there a tidy way to get the behavior I expect? To get this behavior, should I be using ember-changeset at all or is there something much simpler I can do?

This sounds weird to me. A changeset should revalidate when input changes. Do you have a code example? Do you had a look at examples and tests included with ember-changeset-validations?

A changeset should revalidate when input changes.

By “input” do you mean the data coming into the changeset using “set”, i.e. the input to the changeset?

What should I expect to happen if the data that the changeset wraps (what the changeset would ordinarily be writing on a save) is changed from outside the changeset? Should the validation be re-run to eliminate errors from the changeset’s error list that no longer apply? That’s what I was expecting but it appears not to be happening. The data in the changeset is updating to the new values, but the validation function is never invoked and everything in the error list still remains.

I’m not sure what I would expect in that case. On the one hand the philosophy seems to be that the validations aren’t run until something “changes” the changeset (e.g. there is input) by default, and maybe it would be unexpected to have validations refiring in the case of model changes, but then again maybe not. It might also just be that it’s more complex to track state that way so it’s just a technical challenge. It does seem like a reasonable need (whether or not its feasible). I’d try opening an issue to discuss it in the library and maybe someone can share the thinking (if it’s intentional) or consider a feature request if not.

If not that you could probably wire it up to revalidate when your model changes but then you’re using an observer-ish pattern so I see why that’s not ideal.

Yeah, that’s the problem. It seems like changesets were built (or at least tested) with a singular “one changeset per destination” mindset, or possibly a “data has one source and one destination” mindset, rather than a plural “one changeset per source” mindset. This is proving simplistic if you’ve got data that can come from different places with error lists that have to be handled separately.

I was hoping I might get some clarification here from the authors whether this is, in fact, the case. Since the changeset lies between the model data and the GUI, I was wondering if there was anything in the Data-Down side, which is clearly operating in the changeset’s proxy, that could be used to update the error list as well.

If not that you could probably wire it up to revalidate when your model changes but then you’re using an observer-ish pattern so I see why that’s not ideal.

Or I could do something imperative from the action on one changeset to flash other active changesets to revalidate when it successfully performs a save, except that I can’t see a way to imperatively ask a changeset to “revalidate all data, not just the dirty fields”. Setting a field to the same value as the one it proxies doesn’t mark it as dirty, so it won’t even test it, and in this case, we are revalidating to clear errors that no longer apply, not to look for new errors.

So right now, I can’t see how to use changeset-per-source, even using the supplied changesets as primitives. It seems like I’m not provided sufficient mechanisms to do it. It’s frustrating :frowning: