How to display server errors in Angularjs with ng-messages

后端 未结 4 1884
情话喂你
情话喂你 2021-02-02 10:30

I have have my angular app validating a sign-up form. On submit, the server also validates the data. I\'m outputting error messages in angular using ng-messages.

Here i

相关标签:
4条回答
  • 2021-02-02 10:45

    Well, this is not the most elegant solution since you really should leverage the asyncValidators in angular 1.3.x and then create your custom validation directives.

    Resources

    http://plnkr.co/edit/s4jJAOqehBkFUC9osMsy?p=preview found in the post by this guy.

    Possibly here http://odetocode.com/blogs/scott/archive/2014/10/16/working-with-validators-and-messages-in-angularjs.aspx

    And of course in the docs

    But be cautious as this is not in any way a complete example ready to be used. It's mostly here for demo purpose and to sort of give you an idea where to start. I have not bothered with clearing any previous errors, revalidating the form or taken into account other validation errors.

    Awesomeness

    Imagine your controller looks like this

    $scope.serverValidations = {};
    $scope.attemptSignUp = function(){
    
        Api.validateEmail($scope.email).then(angular.noop, function(data){
    
          $scope.serverValidations = data
          for(prop in $scope.serverValidations){
              if($scope.signUpForm[prop]){
                angular.forEach($scope.serverValidations[prop],function(validation){
                    $scope.signUpForm[prop].$setValidity(validation.type, false);
                });
              }
          }
        });
    }
    

    and your response data containing validation errors look like this

    {
      email:[
         {type:'unique', message:'This email is already in use'}
      ],
      name:[
         {type:'maxlength', message:'Your name is to long, get a new one :)'}
      ]
    };
    

    Then in your HTML you could do like this

    <div class="error" data-ng-messages="signUpForm.name.$error" data-ng-cloak="">
        <p data-ng-message="required">You don't have a name?</p>
        <p ng-repeat="validation in serverValidations['name']" ng-message="{{validation.type}}">{{validation.message}}</p>
    </div>
    

    Here's a dirty Codepen for you: http://codepen.io/anon/pen/yyzMgG?editors=101 When you press submit, after 2 seconds (the time it takes to hit the fake server) your server validations are presented.

    0 讨论(0)
  • 2021-02-02 10:56

    First of all you should set validity and error messages

          $scope.formErrors = {};
          angular.forEach(errors, function(data, name) {
            if (!vm.register_form[name]) {
              return;
            }
            $scope.formErrors[name] = data.message;
            //this will set errors->server to invalid state
            $scope.register_form[name].$setValidity('server', false);
          });
    

    The next step will be rendering by ng-messages

          <div ng-messages="register_form.email.$error">
            <div ng-message="required">Email is required</div>
            <div ng-message="email">Invalid email</div>
            <div ng-message="server">{{formErrors.email}}</div>
          </div>
    
    0 讨论(0)
  • 2021-02-02 10:56

    I had a similar question, but the solutions did not work for me. What I did, and it is/was a hack/work around, was to send different errorcodes, and set a case statement.

    0 讨论(0)
  • 2021-02-02 10:59

    A simple solution is to have two arrays. One for client side and one for server side errors which is populated in your controller. You can hide the server side errors if client errors exists or opposit to avoid double messages.

    The reason I choose to have two arrays instead of populating the forms array is that the JavaScript controller should not know or be dependent on the structure of the HTML. The HTML AngularJS template should be bound to the controller, not opposit.

    <form name="signUpForm" novalidate data-ng-submit="attemptSignUp()">
        <label for="email">E-mail
            <input type="email" name="email" id="email" required data-ng-model="data.user.email" />
            <div class="error" data-ng-messages="signUpForm.email.$error" data-ng-show="signUpForm.$submitted" data-ng-cloak>
                <p data-ng-message="required">Please provide your email</p>
            </div>
            <div class="error" data-ng-messages="serverErrors" data-ng-show="signUpForm.$submitted" data-ng-cloak>
                <p data-ng-message="emailexists">Email already exists</p>
            </div>
        </label
    </form>
    

    A note on the label: Users using screen-readers will not get your error messages read out loud to them if they are not wrapped inside the label.

    0 讨论(0)
提交回复
热议问题