0

So I've got a dynamic table that I need to keep track of several properties of. I'm using angularJS to do this and a 2D array of objects to track the elements of the table.

My code looks like this:

$scope.table = [];
$scope.generateTable = function(){
    var table = [[], []];
    for (var i = 0; i < $scope.height; i++) {
        $scope.table[i] = []
        for (var j = 0; j < $scope.width; j++) {
            $scope.table[i].push({
                display: 'X',
                alive: false
            });
        }
    }
}

$scope.changeProp = function(x, y){
    $scope.table[x][y].alive = !$scope.table[x][y].alive;
    $scope.table[x][y].alive ? $scope.table[x][y].display = 'O' : $scope.table[x][y].display = 'X';
}

But it says 'cannot read property of undefined' whenever I try to run the changeProp() function. The elements exist in the array as they should and display properly on the front end, why can't I change the elements in the function with the syntax arr[][]?

EDIT: Upon further review, it appears the problem lies with width not being passed to changeProp properly. Here is the front end code:

<tr ng-repeat="x in table">
    <td ng-repeat="y in x track by $index" align="center" ng-click="changeProp($parent.index, $index)">
        {{ y.display }}
    </td>
</tr>
4
  • When do you call generateTable ? Are you sure width and height are defined and > 0 at that time ? Commented May 3, 2017 at 16:37
  • Are you sure that x and y passed as parameters to changeProp call are not greater than or equal to $scope.height, $scope.width ? Commented May 3, 2017 at 16:41
  • EDIT: Wait, I am in fact not getting a value for width. I will add my ng-repeat code. Commented May 3, 2017 at 16:45
  • @Ajv2324 debug in the browser console. Perfect time when console.log is really helpful Commented May 3, 2017 at 16:48

3 Answers 3

1

You have passed parent index in wrong way.

Edit $parent.index to $parent.$index.

<tr ng-repeat="x in table">
    <td ng-repeat="y in x track by $index" align="center" ng-click="changeProp($parent.$index, $index)">
        {{ y.display }}
    </td>
</tr>
Sign up to request clarification or add additional context in comments.

Comments

1

Pleas try as like below:

$scope.table = [{},{}];
$scope.generateTable = function(){
    var table = [{}, {}];
    for (var i = 0; i < $scope.height; i++) {
        $scope.table[i] = {};
        for (var j = 0; j < $scope.width; j++) {
            $scope.table[i].push({
                display: 'X',
                alive: false
            });
        }
    }
}

$scope.changeProp = function(x, y){
    x =parseInt(x);
    y= parseInt(y);
    $scope.table[x][y]['alive'] = !$scope.table[x][y]['alive'];
    $scope.table[x][y]['alive'] ? $scope.table[x][y]['display'] = 'O' : $scope.table[x][y]['display'] = 'X';
}

IN UI:

<tr ng-repeat="x in table">
    <td ng-repeat="y in x track by $index" align="center" ng-click="changeProp($index==0 ? 0 :$index--, $index)">
        {{ y.display }}
    </td>
</tr>

Comments

0

I've solved the problem.

I needed to init a variable to the index of the ng-repeat.

Example:

<tr ng-repeat="x in table" ng-init="outer = $index">
      <td ng-repeat="y in x track by $index" ng-init="inner = $index" align="center" ng-click="changeProp(outer, inner)">
              {{ y.display }}
      </td>
</tr>

1 Comment

You don't have to use ng-init="outer =$index" for accessing index of parent . You can directly use $parent.$index for this.

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.