Search code examples
javascriptangularjschessangularjs-ng-click

ng-click not executing for td cell


I'm trying to create a chess board in Angular and for the most part and moving from success to success. I've created a data structure that represents the starting position and for now my HTML is as simple as what I've pasted below. The associated code for returning a class works, but I'm trying to add an ng-click handler that takes the same arguments (first row only in HTML below; actually equates to first column, or "A" file on chess board).

However the associated Javascript code for ng-click, actions.move() is not being reached. Below the markup I've pasted some of the Javascript, and beneath that some of the generated DOM. What am I doing wrong?

HTML:

<div ng-controller='ChessBoardController'>
  <table>
    <tr ng-repeat="rank in model.board">
      <td ng-class="styles.square($index, 'A')" ng-click="actions.move($index, 'A')"><span ng-bind-html="rank.A"></span></td>
      <td ng-class="styles.square($index, 'B')" ><span ng-bind-html="rank.B"></span></td>
      <td ng-class="styles.square($index, 'C')" ><span ng-bind-html="rank.C"></span></td>
      <td ng-class="styles.square($index, 'D')" ><span ng-bind-html="rank.D"></span></td>
      <td ng-class="styles.square($index, 'E')" ><span ng-bind-html="rank.E"></span></td>
      <td ng-class="styles.square($index, 'F')" ><span ng-bind-html="rank.F"></span></td>
      <td ng-class="styles.square($index, 'G')" ><span ng-bind-html="rank.G"></span></td>
      <td ng-class="styles.square($index, 'H')" ><span ng-bind-html="rank.H"></span></td>
      </td>
    </tr>
  </table>
</div>

Javascript:

$scope.styles = (function() {
    return {
        square: function(index, file) {
            if ((index + (file.charCodeAt() % 2)) % 2) {
              return 'lightSquare';
            }
            else {
              return 'darkSquare';
            }
        }
    }
})();

$scope.actions = (function() {
    return {
        move: function(index, file) {
            console.log(arguments);
        }
    }
});

Generated DOM:

<td ng-class="styles.square($index, 'A')" ng-click="actions.move($index, 'A')" class="darkSquare"><span ng-bind-html="rank.A" class="ng-binding">♖</span></td>

Solution

  • The problem is with your action function:

    • You declared action as a function which returns an object of function properties.
    • It seems like you wanted to create it as IIFE but you missed () at the end.
    • Why do you need to create it as IIEF anyway?
    • Inside ngClick You try to refer to action as an object: actions.
    • If you were to write actions(). then it would work but that's not needed (see solution).
    • Angular.js ($parse) ignores your mistake without telling you anything.
    • Read my answer to understand why angularjs ng-click silently eats errors

    Solution:

    $scope.actions = {
      move: function(index, file) {
          console.log(arguments);
      }
    }