Reputation: 3884
I generate forms by ng-repeat
-ing over an array. Every generated form is added to an vm.forms
object. When removing an item from the array I'm iterating over the corresponding form is removed, but the vm.forms
object still has a key for the original form, causing me undefined
errors.
angular
.module('myApp', [])
.controller('FormLooper', FormLooper);
function FormLooper() {
var vm = this;
vm.children = [{
name: 'Sarah',
age: 9,
}, {
name: 'John',
age: 13,
}];
vm.removeChild = removeChild;
vm.forms = {};
vm.showSummary = false;
vm.triggerError = triggerError;
function triggerError() {
console.log('Available forms:', vm.forms);
console.log('property names:', Object.getOwnPropertyNames(vm.forms));
Object.getOwnPropertyNames(vm.forms).map(function(key) {
console.log('key', key, vm.forms[key]);
return vm.forms[key].$valid; // This will result in an `undefined` error
});
}
function removeChild(index) {
vm.children.splice(index, 1);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.6/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="FormLooper as vm">
<div ng-repeat="child in vm.children">
<form name="vm.forms.formId{{ $index }}">
<label>
Name: <input ng-model="child.name">
</label>
<br>
<label>
Age: <input type="number" ng-model="child.age">
</label>
</form>
<button ng-click="vm.removeChild($index)">RemoveChild</button>
</div>
<button ng-click="vm.triggerError()">Trigger Error (check your console output)</button>
</div>
</body>
Or, the same code as a JSFiddle: http://jsfiddle.net/Tobbe/8eohL2nq/2/
Shouldn't angular delete the entire object property?
I could solve this by manually delete
-ing the object property in the removeChild
function, but in my actual code I don't want to mix these concerns like that. Another simple solution is to just check for undefined
or similar in the function that map
calls. But it doesn't feel like I should have to resort to that...
So, am I missing something here?
EDIT:
Please pay attention to the console output and notice that the vm.forms
object is properly populated when the forms are created. Angular does this all on its own :) So it adds to the object when the forms are created, but it doesn't delete from the object when the forms are removed. Is this a bug?
Upvotes: 2
Views: 237
Reputation: 3884
The behavior I want should be handled by the AngularJS parser, but it is not supported right now. Easiest workaround right now is to just check for undefined
on access.
See more here: https://github.com/angular/angular.js/issues/14510
Upvotes: 0
Reputation: 987
You are working with apples and peaches...
You try to use vm.forms.formid{{$index}} which will search for an vm.forms object. Which you never initialize.
You have two options: 1. Work with the children array:
<div ng-repeat="child in vm.children">
<form name="vm_forms_formId{{ $index }}">
<label>
Name: <input ng-model="child.name">
</label>
<br>
<label>
Age: <input type="number" ng-model="child.age">
</label>
</form>
</div>
which will give you valid form names (you could also use IDs of the children).
Upvotes: 1