Q:

Angularjs: Why is $scope.variable in $watch not up-to-date?

I created a Plunker here to illustrate the problem. Here is the main code:
<body ng-controller="MainCtrl">
  <table class="table table-bordered table-striped table-condensed table-hover">
      <caption class="text-left" style="background-color: lightgray">
          Search: <input ng-model="searchString" style="width: 80px" />
          Filted count: {{filteredList.length}}
      </caption>
    <thead>
      <tr>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Sex</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="emp in filteredList = (data.employees | filter:searchString)">
        <td>{{emp.firstName}}</td>
        <td>{{emp.lastName}}</td>
        <td>{{emp.sex}}</td>
      </tr>
    </tbody>
  </table>
</body>

App.js:
$scope.searchString = '';
$scope.$watch('searchString', function(str) {
  console.log($scope.filteredList.length);
});    

The problem is that the console.log of filteredList.length is always one loop behind (compared to html which is correct), that is, from previous filter. How can I fix it?

A:

You are logging filteredList.length as soon as searchString changes.  But, at at moment, filteredList has not yet been modified by the filter in ngRepeat.  
One way to fix this would be to $watch filteredList.length instead:
$scope.$watch(function() {
  return ($scope.filteredList || []).length;
...

Update
I really like shaunhusain's comment.  His suggestion is probably closer to what you really want to do.
$scope.searchString = '';
// Initialize filteredItems as a copy of data.employees
$scope.filteredItems = angular.copy($scope.data.employees);

// Watch your search string instead and apply filtering using $filter
$scope.$watch(function() {
    return $scope.searchString;
  }, 
  function(str) {
    $scope.filteredItems = $filter('filter')($scope.data.employees, {$: $scope.searchString}, false);
    console.log($scope.filteredItems.length);
  });

Then, your ngRepeat is simply:
  <tr ng-repeat="emp in filteredItems">
    <td>{{emp.firstName}}</td>
    <td>{{emp.lastName}}</td>
    <td>{{emp.sex}}</td>
  </tr>

