Why does setting ng-model to undefined not make the form/input valid again?

I have the following simple form with an type='email' input bound to a model:

<div ng-app>
    <h2>Clearing ng-model</h2>
    <div ng-controller="EmailCtrl">
        <form name="emailForm" ng-submit="addEmail()">
            <input type="email" name="email" ng-model="userEmail" placeholder="[email protected]">
            <span ng-show="emailForm.email.$invalid && emailForm.email.$dirty">invalid email</span>
            <span ng-show="emailForm.$invalid">form invalid!</span>
        <button ng-click="clearViaUndefined()">clear via undefined</button>
        <button ng-click="clearViaNull()">clear via null</button>
        <button ng-click="clearViaEmptyString()">clear via empty string</button>

Suppose the user enters an invalid email but then clicks a 'Cancel' button...so the form needs to be reset.

In the ng-click handler for the 'Cancel' button, if I set the value of the model to 'undefined' this does not change the input element's $valid property back to true (nor the form's for that matter).

function EmailCtrl($scope) {

    $scope.clearViaUndefined = function () {
        $scope.userEmail = undefined;

    $scope.clearViaNull = function () {
        $scope.userEmail = null;

    $scope.clearViaEmptyString = function () {
        $scope.userEmail = "";

If I set the value of the model to an empty string "" or to null, then the $valid property does get set back to true.

Why is this?

I have a JS Fiddle here demonstrating the behaviour:




Whenever you use ng-model on an input or select tag, angular internally manages two values for the field, one is $viewValue and other is $modelValue

$viewValue -> Used for display purpose on view

$modelValue-> Actual value which is used inside scope.

When using an input tag with type='email' Angular constantly validates the input value.

And if the value does not validate as a correct email, angular internally will set $modelValue to undefined and will set the form.fieldName.$error.fieldName attribute to true. So that field becomes invalid.

If you check the value of form.fieldName.$modelValue inside the controller you will find it as undefined.

So setting the model to 'undefined' in the controller, when the field is already invalid, changes nothing.

But if you set it to null or "" it will work as $modelValue and $viewValue both get changed - making the field valid again.

Hope this has cleared your understanding. Thanks.


Add ng-model-options="{allowInvalid: true}" on input field

then try setting ng-model to undefined hopefully will make the form/input valid again

see: https://docs.angularjs.org/api/ng/directive/ngModelOptions


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.