Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 (Beta) Server side validation messages

I am looking for an elegant way to display validation messages from a server side API without having to create custom validators or hard coding all possible messages in the UI.

I need to add error messages to specific fields as well as to the entire form.

This must work in Angular 2.0.0-beta.3

like image 602
Steve Powell Avatar asked Feb 08 '16 22:02

Steve Powell


2 Answers

There are two kinds of server validations:

  • The global ones (for the whole form or corresponding to an error during the form submission)
  • The ones related to fields

For the one, simply extract the message from the response payload and put it into a property of your component to display it into the associated template:

@Component({
  (...)
  template: `
    <form (submit)="onSubmit()">
      (...)
      <div *ngIf="errorMessage">{{errorMessage}}</div>
      <button type="submit">Submit</button>
    </form>
  `
})
export class MyComponent {
  (...)

  onSubmit() {
    this.http.post('http://...', data)
             .map(res => res.json())
             .subscribe(
               (data) => {
                 // Success callback
               },
               (errorData) => {
                 // Error callback
                 var error = errorData.json();
                 this.error = `${error.reasonPhrase} (${error.code})`;
               }
             );
  }
}

I assume that the response payload for error is a JSON one and corresponds to the following:

{
  "code": 422,
  "description": "Some description",
  "reasonPhrase": "Unprocessable Entity"
}

For the second one, you can set received error message within controls associated with form inputs, as described below:

@Component({
  (...)
  template: `
    <form [ngFormModel]="myForm" (submit)="onSubmit()">
      (...)
      Name: <input [ngFormControl]="myForm.controls.name"/>
      <span *ngIf="myForm.controls.name.errors?.remote"></span>
      (...)
      <button type="submit">Submit</button>
    </form>
  `
})
export class MyComponent {
  (...)

  constructor(builder:FormBuilder) {
    this.myForm = this.companyForm = builder.group({
      name: ['', Validators.required ]
    });
  }

  onSubmit() {
    this.http.post('http://...', data)
             .map(res => res.json())
             .subscribe(
               (data) => {
                 // Success callback
               },
               (errorData) => {
                 // Error callback
                 var error = errorData.json();
                 var messages = error.messages;
                 messages.forEach((message) => {
                   this.companyForm.controls[message.property].setErrors({
                     remote: message.message });
                 });
               }
             );
  }
}

I assume that the response payload for error is a JSON one and corresponds to the following:

{
  messages: [
    {
      "property": "name",
      "message": "The value can't be empty"
  ]
}

For more details you can have a look at this project:

  • https://github.com/restlet/restlet-sample-angular2-forms/blob/master/src/app/components/company.details.ts
  • https://github.com/restlet/restlet-sample-angular2-forms/blob/master/src/app/components/form.field.ts
like image 76
Thierry Templier Avatar answered Nov 14 '22 21:11

Thierry Templier


I present you the definitive displayErrors function (Handles server side validations following the JSONAPI Standard):

You will need Underscore.js

displayErrors(error: ErrorResponse) {
  let controls = this.supportRequestForm.controls;
  let grouped = _.groupBy(error['errors'], function(e) {
    return e['source']['pointer'];
  });
  _.each(grouped, function(value, key, object) {
    let attribute = key.split('/').pop();
    let details = _.map(value, function(item) { return item['detail']; });

    controls[attribute].setErrors({ remote: details.join(', ') });
  });
}
like image 40
victorhazbun Avatar answered Nov 14 '22 22:11

victorhazbun