30

Is there any way to pass an error message in custom form validation?

E.g. I have a directive that checks a username. There are three possible outcomes:

  1. It is valid
  2. It is invalid because it isn't a good username ("this.is-invalid")
  3. It is invalid because it is already in use

I have a directive like (simplified pseudo-html):

<input type="text" namecheck></input><span ng-show="name.$error.namecheck">You had an error {{ error }}</span>

And in my custom directive, I can do

// check for a conflict and valid name here
ngModel.$setValidity("namecheck",false);

But how do I pass an error message that indicates if the problem was a conflict or invalid name? Is there anything like ngModel.$setValidityErrorMessage() ?

2
  • @Whisher, so there is no way to inform the UI what the invalidity was? Can I perhaps set an error message on the scope from within the directive link? Commented Oct 22, 2013 at 15:04
  • Ha! Just figured it out! I can use different validities! ngModel.$setValidity('nameunique',false) is different than ngModel.$setValidity('nameinvalid',false) Commented Oct 22, 2013 at 15:50

3 Answers 3

51

As I wrote in the comments, I just figured it out. I just need to use different validity flags. Nothing says that I have to use the same key in $setValidity() as the name of the directive!

<span ng-show="name.$error.nameinvalid">This is not a valid username, it must be alphanmueric</span>
<span ng-show="name.$error.nametaken">Sorry, the username {{ name }} is already taken</span>

And in the directive

// if I got a 409
ngModel.$setValidity("nametaken",false);
// if I got a 400
ngModel.$setValidity("nameinvalid",false);

The name of the $error is the error message!

Sign up to request clarification or add additional context in comments.

2 Comments

You could also just bind a model within your directive, and add your error message here (if you have many different error messages that come from the server)
Can you please provide example of this?
2

No. Setting the validity on a form element just simply adds the appropriate class to the element, which can then be used to style the element to indicate an error. There aren't any error messages that indicate why the element is invalid. Angular doesn't provide that support.

You may have noticed error messages that pop up on required fields that are empty? In chrome they say something like: "Please fill out this field" or something. Those are browser-specific and aren't related to angular in any way.

You'd have to roll your own error messaging service. You can use the same ng-invalid classes to check when a form element is invalid and show the error messages based on that, but Angular doesn't provide that out of the box.

There is an example in the angular docs (found here) that shows one way you can do that.

UPDATE:

As of Angular 1.3, there is now support for the ngMessage and ngMessages directives. These new directives attempt to make form validation and error messaging less of a hassle. The angular docs for these directives are here. Check the link out for more details.

2 Comments

I am OK with that, but my question was how I can set specific error messages from within the directive?
Yeah, sorry. The angular 1.2-rc3 docs have a hard time with absolute links. Here's a link to the angular 1.5 docs that have that same example: code.angularjs.org/1.1.5/docs/api/ng.directive:form. Hope that helps.
2

In my opinion, your three rules include both client and server validation. I'll validate the first two in client side, and the validate last rule in server side. Because an username is duplicate or not, we get it until we post it to the server. So, my practice is following:

 <div class="col-md-offset-3 col-md-9" ng-show="detailForm.$error && detailForm.name.$invalid && (detailForm.name.$touched || detailForm.$submitted)"
                     ng-messages="detailForm.name.$error">
          <div class="error-message" ng-message="required">the field is required </div>
          <div class="error-message" ng-message="maxlength">you are too lang</div>
          <div class="error-message" ng-message="pattern">your format is incorrect </div>
 </div>
 <div class="col-md-offset-3 col-md-9" ng-show="serverError && serverError.name">
          <div class="error-message">{{serverError.name}}</div>
 </div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.