Caballero
Caballero

Reputation: 12101

Angularjs ng-repeat, ng-form and validation error

A simplified version of the code:

<!DOCTYPE html>
<html ng-app="main">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.angularjs.org/1.4.3/angular.min.js"></script>
    <script>
        var app = angular.module("main", []);
        app.controller("TestController", function($scope) {
            $scope.addresses = [{street: ""}, {street: ""}];
            $scope.next = function() {
                if ($scope.addressMainForm.addressForm.$valid) {
                    console.log("valid");
                } else {
                    console.log("invalid");
                }
                $scope.addresses.push({street: ""});
            };
            $scope.remove = function(index) {
                $scope.addresses.splice(index, 1);
            };
        });
    </script>
</head>
<body>

    <div ng-controller="TestController" style="width: 500px;">
        <form name="addressMainForm">
            <div ng-repeat="address in addresses">
                <ng-form name="addressForm">
                    <input ng-model="address.street" required name="street" type="text" placeholder="street" />
                    <button ng-if="$index > 0" ng-click="remove($index)">REMOVE</button>
                </ng-form>
                <br>
            </div>
        </form>
        <br>
        <button ng-click="next()">NEXT</button>
    </div>

</body>
</html>

which looks in the browser like this:

enter image description here

When I click "REMOVE" and then "NEXT" - javascript error is produced:

Error: $scope.addressMainForm.addressForm is undefined

Why is it undefined if there is clearly still one element remaining in the array? Everything otherwise works fine (console.log output), until all the elements are removed but the last one and "NEXT" is clicked.

Upvotes: 0

Views: 326

Answers (1)

Gnarlywhale
Gnarlywhale

Reputation: 4220

When you call $scope.addressMainForm.addressForm.$valid , you are attempting to call check to see if the adressForm element is valid, but your remove function has removed the addresses entry associated with that element. So the form indeed still exists, but that call becomes illegal.

Try this:

<!DOCTYPE html>
<html ng-app="main">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript" src="https://code.angularjs.org/1.4.3/angular.min.js"></script>
    <script>
        var app = angular.module("main", []);
        app.controller("TestController", function($scope) {
            $scope.addresses = [{street: ""}, {street: ""}];
            $scope.next = function() {
                if ($scope.addressMainForm.$valid) {
                    console.log("valid");
                } else {
                    console.log("invalid");
                }
                $scope.addresses.push({street: ""});
            };
            $scope.remove = function(index) {
                $scope.addresses.splice(index, 1);
            };
        });
    </script>
</head>
<body>

    <div ng-controller="TestController" style="width: 500px;">
        <form name="addressMainForm">
            <div ng-repeat="address in addresses">
                <ng-form name="addressForm">
                    <input ng-model="address.street" required name="street" type="text" placeholder="street" />
                    <button ng-if="$index > 0" ng-click="remove($index)">REMOVE</button>
                </ng-form>
                <br>
            </div>
        </form>
        <br>
        <button ng-click="next()">NEXT</button>
    </div>

</body>
</html>

Upvotes: 1

Related Questions