1

i'm learning from tutorial "Creating Apps With Angular, Node, and Token Authentication". And i've stuck. I found this code there:

html

<form name="register" class="form-signin" novalidate>
    <h1 class="form-signin-heading text-muted">Register</h1>
    <input type="email" ng-model="email" name="email"
           class="form-control" placeholder="Email address"
           required autofocus>
    <p class="help-block"
       ng-show="register.email.$dirty && register.email.$invalid">
      Please enter a proper email.
    </p>
    <input type="password" name="password" ng-model="password"
           class="form-control" placeholder="Password" required>
    <input type="password" name="password_confirm" ng-model="password_confirm"
           class="form-control" placeholder="Confirm Password"
           validate-equals="password">
    <p class="help-block"
       ng-show="register.password_confirm.$invalid && register.password_confirm.$dirty">
      please match the passwords.
    </p>
    <button ng-disabled="register.$invalid" class="btn btn-lg btn-primary btn-block" type="submit">
        Submit
    </button>
</form>

and js

angular.module('myApp', []).directive('validateEquals', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            function validateEqual(value) {
                var valid = (value === scope.$eval(attrs.validateEquals));
                ngModelCtrl.$setValidity('equal', valid);
                return valid ? value : undefined;
            }
            ngModelCtrl.$parsers.push(validateEqual);
            ngModelCtrl.$formatters.push(validateEqual);
            scope.$watch(attrs.validateEquals, function() {
                ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue);
            });

        }
    };
});

this directive according to the video should give me a proper two-way validation for password and password_confirm inputs, but it doesn't (on video it does work, i'm confused). It validates well, when i change value of password_confirm but when i change password, validation not work. Here is plunker plunker. Question: What's wrong with that code? And how should i fix it?

2 Answers 2

2

The problem probably is in this line:

ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue);

This line doesn't do anything. I gues sthat in a previous version of Angular, it retriggered the $parsers pipeline, and that in the current version, since it sets the view value to the same value that it already has, it has been optimized to not do anything.

This really looks like a hack to me. It should be replaced by something like

scope.$watch(attrs.validateEquals, function(firstPassword) {
    var valid = (ngModelCtrl.$modelValue === firstPassword);
    ngModelCtrl.$setValidity('equal', valid);
});

(not tested)

BTW, angular now has support for validators, which make things easier and don't force you to deal with parsers and formatters: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController.

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

1 Comment

Thx a lot, validators are the right way, i will post my new working directive.
1

Solution found, Thanks to JB Nizet :)

solution :

angular.module('learningAngularApp')
.directive('validateEquals', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attrs, ngModelCtrl) {
            ngModelCtrl.$validators.validateEqual = function(modelValue, viewValue) {
                var value = modelValue || viewValue;
                var valid = (value === scope.$eval(attrs.validateEquals));
                return valid;
            }
            scope.$watch(attrs.validateEquals, function () {
                ngModelCtrl.$validate();
            });

        }
    };
});

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.