Octtavius Octtavius - 2 years ago 73
AngularJS Question

Cannot read 'xyxyx' property of undefined even if element exist

I have two HTML inputs (

type="email"
,
type="number"
) and my Angular app watches them using
$formatters
and
$parsers
. The errors are stored in an array and when user insert an email which contains "@gmail" the error is removed from the array.

app.controller('form1Controller', function($scope, UserService) {
$scope.formCompleted = false;
$scope.errors = UserService.errors;

//handle the user email input.
$scope.storeEmailErr = function(data) {

var correctKey = "@gmail";
var key = "#userEmail";

var res = {};

if (data != null) {
res = $scope.handleError(data, emailIn, correctKey, key, $scope.errors);
$scope.errors = res[0];
UserService.errors = res[0];
emailIn = res[1];
}
};

//handle the user email input.
$scope.storeIdErr = function(data) {

var correctKey = "0000";
var key = "#userId";

var res = {};

if (data != null) {
res = $scope.handleError(data, idIn, correctKey, key, $scope.errors);
$scope.errors = res[0];
idIn = res[1];
}

};
}


This is the code that adds and removes errors from array. And here i suppose is the problem

function theIndexOf(val) {
console.log("find index in array of length: " + errorsDescription.length)
for (var i = 0; i < errorsDescription.length; i++) {
if (errorsDescription[i].selector === val) {
return i;
}
}
}

app.run(function($rootScope){
$rootScope.handleError = function(data, elemIn, correctKey, key, errorArray){
var idx = theIndexOf(key);
console.log("get index >>>>> " + idx);
var obj = errorsDescription[idx];

//if user didn't put correct word i.e. @gmail or 0000
if (data.indexOf(correctKey) < 0) {
if (!elemIn) {
errorArray.push(obj);
elemIn = true;
}
} else {
if (elemIn) {
$.each(errorArray, function(i){
if(errorArray[i].selector === key) {
errorArray.splice(i, 1);
elemIn = false;
}
});
}
}
return [errorArray, elemIn];
}
});


The problem is that when I insert i.e. "test@gmail.com", the error is deleted from the array and when I insert correct data again it tells me that cannot read 'yyy' property of undefined.

Here is my plunker.
https://plnkr.co/edit/l0ct4gAh6v10i47XxcmT?p=preview

In the plunker, type in the fields 'test@gmail' and test0000 for the Number, then remove data then insert again the same data to see the problem

Any help would be much appreciated!

Answer Source

EDIT: Working plunkr here: https://plnkr.co/edit/8DY0Cd5Pvt6TPVYHbFA4

The issue is here:

var obj = errorsDescription[idx];

//if user didn't put correct word i.e. @gmail or 0000
if(data.indexOf(correctKey) < 0){
    // console.log("You must put correct word");
    if(!elemIn){
        errorArray.push(obj);
        elemIn = true;
    }
}

When your Personal Number error is removed, the logic above pushes undefined to your errorArray (because elemIn is false). Your storeIdErr methond:

$scope.storeIdErr = function(data){

    var correctKey = "0000";
    var key = "#userId";

    var res = {};

    if(data != null){
        res = $scope.handleError(data, idIn, correctKey, key, $scope.errors);
        $scope.errors = res[0];
        idIn = res[1];
    }

};

reads this value (res[0]) and stores it in $scope.errors which ultimately is iterated over on the next input event by:

function theIndexOf(val){
    console.log("find index in array of length:  " + errorsDescription.length)
    for(var i = 0; i < errorsDescription.length; i++){
        if(errorsDescription[i].selector === val){
            return i;
        }
    }
}

due to your factory returning that object when asked for errors. To fix this, you should keep a static list that you never remove from which provides the error definitions. This is what you should refer to when you push to errorArray in your first code block.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download