AngularJS password confirmation noMatch not working?

Problem

I have this script here:

angular.module('UserValidation', []).directive('validPasswordC', function () {
    return {
        require: 'ngModel',
        link: function (scope, elm, attrs, ctrl) {
            ctrl.$parsers.unshift(function (viewValue, $scope) {
                var noMatch = viewValue != scope.signupForm.password.$viewValue
                ctrl.$setValidity('noMatch', !noMatch)
            })
        }
    }
});    

And here's the html:

<div class="fieldset" ng-class="{'has-error':formData.password.$invalid && !formData.password.$pristine}">
   <label>Password</label>
   <input type="password" id="password" name="password" ng-model="formData.password" ng-minlength="8" ng-maxlength="20" ng-pattern="/(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z])/" placeholder="password" required />

   <p ng-show="signupForm.password.$error.required" class="error">*</p>
   <p ng-show="signupForm.password.$error.minlength" class="error">
      Passwords must be between 8 and 20 characters.</p>
   <p ng-show="signupForm.password.$error.pattern" class="error">
      Must contain one lower &amp; uppercase letter, and one non-alpha character (a number or a symbol.)</p>
</div>

<div class="fieldset" ng-class="{'has-error':formData.password_c.$invalid && !formData.password_c.$pristine}">
   <label for="password_c">Confirm Password</label>
   <input type="password" id="password_c" name="password_c" ng-model="formData.password_c" placeholder="confirm password" valid-password-c required />

   <p ng-show="signupForm.password_c.$error.noMatch" class="error">Passwords do not match.</span>
   <p ng-show="signupForm.password_c.$error.required" class="error">*</p>
</div>    

The character validation for password is working, but the "noMatch" function for confirm password is not working.

What might be the problem? Thanks! :)

Problem courtesy of: kgam

Solution

You need to pass your original password to directive as well/

Please see working demo below

var app = angular.module('app', []);
app.directive('validPasswordC', function() {
  return {
    require: 'ngModel',
    scope: {

      reference: '=validPasswordC'

    },
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue, $scope) {

        var noMatch = viewValue != scope.reference
        ctrl.$setValidity('noMatch', !noMatch);
        return (noMatch)?noMatch:!noMatch;
      });

      scope.$watch("reference", function(value) {;
        ctrl.$setValidity('noMatch', value === ctrl.$viewValue);

      });
    }
  }
});
app.controller('homeCtrl', function($scope) {




});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
  <div ng-controller="homeCtrl">
    <p>Password:{{formData.password}}</p>
    <form name="signupForm">
      <div class="fieldset" ng-class="{'has-error':formData.password.$invalid && !formData.password.$pristine}">
        <label>Password</label>
        <input type="password" id="password" name="password" ng-model="formData.password" ng-minlength="8" ng-maxlength="20" ng-pattern="/(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z])/" placeholder="password" required />

        <p ng-show="signupForm.password.$error.required" class="error">*</p>
        <p ng-show="signupForm.password.$error.minlength" class="error">
          Passwords must be between 8 and 20 characters.</p>
        <p ng-show="signupForm.password.$error.pattern" class="error">
          Must contain one lower &amp; uppercase letter, and one non-alpha character (a number or a symbol.)</p>
      </div>

      <div class="fieldset" ng-class="{'has-error':formData.password_c.$invalid && !formData.password_c.$pristine}">
        <label for="password_c">Confirm Password</label>
        <input type="password" id="password_c" name="password_c" ng-model="formData.password_c" placeholder="confirm password" valid-password-c="formData.password" required />

        <p ng-show="signupForm.password_c.$error.noMatch" class="error">Passwords do not match.</span>
          <p ng-show="signupForm.password_c.$error.required" class="error">*</p>
      </div>
    </form>
  </div>
</div>

Solution courtesy of: sylwester

Discussion

The easiest is this one.But i don't know this is the good way of coding.

<input ng-model="password" name="user_password" type="password" ng-required="true"  >
<input ng-model="confirmPassword" name="user_password" type="password" ng-required="true"  >
<span ng-show="pasword !== confirmPassword">Password mismatch</span>
Discussion courtesy of: santhosh

The following also will work to verify the confirm password.

<div ng-app="myapp"  ng-controller="mainController as mnCtrl">
<form name="mnCtrl.useradd" ng-submit="mnCtrl.frmAdd()" novalidate  role="form">

<input ng-model="mnCtrl.fields.password" name="user_password" type="password" ng-required="true"  >

<input ng-model="mnCtrl.fields.cpassword"   name="user_cpassword" type="password" ng-required="true"  > 

<div ng-show=" mnCtrl.useradd.user_cpassword.$viewValue != '' && (mnCtrl.useradd.user_password.$viewValue != mnCtrl.useradd.user_cpassword.$viewValue)      ">Fields do not match!</div>

</form>
</div>
Discussion courtesy of: jinson

This recipe can be found in it's original form on Stack Over Flow.