0

I've noticed something odd in AngularJS 1.7.9.

If I use the code <input type="text" ng-model="object.property">, and empty the control (i.e., set its value to an empty string), then object.property also gets set to an empty string – which is what I want and expect.

However, if I add the required attribute to the <input>, and empty the control, then property gets removed from object entirely!

Is this intended behavior? If so, is there a workaround?

The DEMO

angular.module("app",[])
.controller('requiredTestController', ['$scope', function ($scope) {
    
    $scope.user = {
        name: 'delete this text'
    };
    
    $scope.userWithRequiredName = {
        name: 'delete this text'
    };
    
}]);
<script src="//unpkg.com/angular/angular.js"></script>

<body ng-app="app" ng-controller="requiredTestController">

    <p>user: {{ user }}</p>
    <input type="text" ng-model="user.name">
    
    <hr>
    
    <p>userWithRequiredName: {{ userWithRequiredName }}</p>
    <input type="text" ng-model="userWithRequiredName.name" required>

</body>

1
  • It seems that this is intended behavior: "The default behaviour in ngModel is that the model value is set to undefined when the validation determines that the value is invalid." docs.angularjs.org/api/ng/directive/ngModelOptions That seems very weird to me – I'd expect it to set the property to null instead. Commented Mar 4, 2020 at 18:13

2 Answers 2

1

By default invalid values are not stored into model (null is saved instead), and empty string is not valid in your case, to change this add:

ng-model-options="{allowInvalid: true}
Sign up to request clarification or add additional context in comments.

1 Comment

It's not saving null into the model, though. It's removing the property entirely.
0

Use ng-model-options="{allowInvalid: true}":

For more information, see

The DEMO

angular.module("app",[])
.controller('requiredTestController', ['$scope', function ($scope) {
    
    $scope.user = {
        name: 'delete this text'
    };
    
    $scope.userWithRequiredName = {
        name: 'delete this text'
    };
    
}]);
<script src="//unpkg.com/angular/angular.js"></script>

<body ng-app="app" ng-controller="requiredTestController">

    <p>user: {{ user }}</p>
    <input type="text" ng-model="user.name">
    
    <hr>
    
    <p>userWithRequiredName: {{ userWithRequiredName }}</p>
    <input type="text" ng-model="userWithRequiredName.name"
           ng-model-options="{allowInvalid: true}" required>

</body>

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.