ember-changeset icon indicating copy to clipboard operation
ember-changeset copied to clipboard

Better way of handling server-side errors?

Open adambedford opened this issue 8 years ago • 3 comments

I see that #52 gives an example of adding server errors to the changeset so they are visible to the user but this strikes me as somewhat verbose, especially if it is required on many models/save() actions.

Is there a better way to approach this, perhaps by building it into the library? Or could something be accomplished with a service of some sort?

adambedford avatar Jun 21 '17 23:06 adambedford

I agree this should be handled automatically by the library, and I'd suggest that #save() should do this (same as it automatically clears the changes when saving the underlying object is successful).

I'd take this a step further and suggest that the #errors property should be a DS.Errors object such that it can be treated in the same way. As it stands, rendering errors for a particular field will be unnecessarily tricky & unwieldy (unless there's a simpler way to do this I haven't thought of?):

<input class={{if filterErrors(model.errors, 'foo') "is-invalid"}} type="text" value="model.foo" onChange={{action (mut model.foo)}}>
{{#each filterErrors(model.errors, 'foo') as |error|}}
  <small class="invalid-feedback">{{error.message}}</small>
{{/each}}

(and that's assuming I implement some filterErrors helper that will filter errors by attribute name.)

IMO, at the very least, errors should be a hash keyed to attribute name. I'll take a stab at making it happen in a PR tonight.

[EDIT] OK somehow I missed the error object that is keyed to attribute names. Derp. 🤦‍♂️

sdhull avatar Nov 29 '17 22:11 sdhull

@adambedford I like this idea. We could try to make Changeset more extensible (also see https://github.com/poteto/ember-changeset/issues/178), such that consumers of the addon only have to write the "Handling server errors" code once.

Currently triaging issues, so I will leave this open if anyone has suggestions.

nucleartide avatar Jan 11 '18 03:01 nucleartide

@nucleartide FWIW I wrote an error-messages component (template-only) to display errors:

{{#if errors.validation}}
  {{!-- ember-changeset --}}
  {{#each errors.validation as |error|}}
    <div class="invalid-feedback">
      {{error}}
    </div>
  {{/each}}
{{else}}
  {{!-- ember-data --}}
  {{#each errors as |error|}}
    <div rel="{{error.attribute}}" class="invalid-feedback">
      {{error.message}}
    </div>
  {{/each}}
{{/if}}

And it's used like this:

{{!-- changeset --}}
{{input value=pageChangeset.title class=(if pageChangeset.error.title "is-invalid")}}
{{error-messages errors=pageChangeset.error.title}}

{{!-- ember data --}}
{{input value=page.title class=(if page.errors.title "is-invalid")}}
{{error-messages errors=page.errors.title}}

The class assignment is kinda verbose and annoying but I have't figured out how to shorten it yet... 🤔

sdhull avatar Jan 11 '18 08:01 sdhull