Collection-repeat, cannot read property 'isLetter' of undefined


#1

Hi there,

I have been attempting to follow the ‘collection-repeat’ tutorial from this codepen, and I have copied the syntax exactly.

JS

angular.module('contactsApp', ['ionic'])
.controller('MainCtrl', function($scope, $ionicScrollDelegate, filterFilter) {
  var letters = $scope.letters = [];
  var contacts = $scope.contacts = [];
  var currentCharCode = 'A'.charCodeAt(0) - 1;

  //window.CONTACTS is defined below
  window.CONTACTS
    .sort(function(a, b) {
      return a.last_name > b.last_name ? 1 : -1;
    })
    .forEach(function(person) {
      //Get the first letter of the last name, and if the last name changes
      //put the letter in the array
      var personCharCode = person.last_name.toUpperCase().charCodeAt(0);
      //We may jump two letters, be sure to put both in
      //(eg if we jump from Adam Bradley to Bob Doe, add both C and D)
      var difference = personCharCode - currentCharCode;
      for (var i = 1; i <= difference; i++) {
        addLetter(currentCharCode + i);
      }
      currentCharCode = personCharCode;
      contacts.push(person);
    });

  //If names ended before Z, add everything up to Z
  for (var i = currentCharCode + 1; i <= 'Z'.charCodeAt(0); i++) {
    addLetter(i);
  }

  function addLetter(code) {
    var letter = String.fromCharCode(code);
    contacts.push({
      isLetter: true,
      letter: letter
    });
    letters.push(letter);
  }

  //Letters are shorter, everything else is 52 pixels
  $scope.getItemHeight = function(item) {
    return item.isLetter ? 40 : 100;
  };
  $scope.getItemWidth = function(item) {
    return '100%';
  };

  $scope.scrollBottom = function() {
    $ionicScrollDelegate.scrollBottom(true);
  };

  var letterHasMatch = {};
  $scope.getContacts = function() {
    letterHasMatch = {};
    //Filter contacts by $scope.search.
    //Additionally, filter letters so that they only show if there
    //is one or more matching contact
    return contacts.filter(function(item) {
      var itemDoesMatch = !$scope.search || item.isLetter ||
        item.first_name.toLowerCase().indexOf($scope.search.toLowerCase()) > -1 ||
        item.last_name.toLowerCase().indexOf($scope.search.toLowerCase()) > -1;

      //Mark this person's last name letter as 'has a match'
      if (!item.isLetter && itemDoesMatch) {
        var letter = item.last_name.charAt(0).toUpperCase();
        letterHasMatch[letter] = true;
      }

      return itemDoesMatch;
    }).filter(function(item) {
      //Finally, re-filter all of the letters and take out ones that don't
      //have a match
      if (item.isLetter && !letterHasMatch[item.letter]) {
        return false;
      }
      return true;
    });
  };

  $scope.clearSearch = function() {
    $scope.search = '';
  };
});

HTML

<a class="item my-item"
        collection-repeat="item in getContacts()"
        collection-item-height="getItemHeight(item)"
        collection-item-width="getItemWidth(item)"
        ng-href="https://www.google.com/#q={{item.first_name + '+' + item.last_name}}"
        ng-style="{'line-height': getItemHeight(item) + 'px'}"
        ng-class="{'item-divider': item.isLetter}">
        <img ng-if="!item.isLetter" ng-src="http://placekitten.com/60/{{55 + ($index % 10)}}">
        {{item.letter || (item.first_name+' '+item.last_name)}}
      </a>

However I am presented with the following error when I try to run:

Cannot read property ‘isLetter’ of undefined

which is encountered at the following line:

  $scope.getItemHeight = function(item) {
	return item.isLetter ? 40 : 100;
  };

There is no difference to the codepen tutorial in any way (the data for the contacts is included in the JS file but contains over 3000 entries so I omitted it from this post)

Any thoughts on how I can fix this would be appreciated.

Thanks


#2

Hmm are you sure you copied it 100%? I’m not getting that error in the codepen