ng-change directive triggered before model is updated when clicking uib-button-radio element

Here’s a plnkr: https://plnkr.co/edit/bJ6LSR7fAY9mlvqBzDUw?p=preview

I’m using uib-button-radio elements to toggle the active filter on an ng-repeat.

  <div ng-controller="ButtonsCtrl as $ctrl">
    <h4>Radio</h4>
    <pre>Model: {{$ctrl.radioModel}}</pre>
    <div class="btn-group">
      <label class="btn btn-primary" ng-change="$ctrl.do()" ng-model="$ctrl.radioModel" uib-btn-radio="'Left'">Left</label>
      <label class="btn btn-primary" ng-change="$ctrl.do()" ng-model="$ctrl.radioModel" uib-btn-radio="'Middle'">Middle</label>
      <label class="btn btn-primary" ng-change="$ctrl.do()" ng-model="$ctrl.radioModel" uib-btn-radio="'Right'">Right</label>
    </div>

    <p ng-repeat="item in $ctrl.filtered = ($ctrl.collection | filter: { Value: $ctrl.radioModel } )">{{item | json}}</p>

    <p>First filtered item: {{$ctrl.active | json}}</p>

ng-change/ng-click function:

  ctrl.do = function() {
    ctrl.active = ctrl.filtered[0];
  }

When the selected filter changes, and subsequently the collection is updated, I want to select the first item in the filtered collection. However it appears that the ng-change/ng-click function is firing before the collection is updated by the filter.

Answer

What you can do is apply the filtering logic in JavaScript instead of in the markup.

In the HTML, change the ng-repeat expression to just:

<p ng-repeat="item in $ctrl.filtered">{{item | json}}</p>

In the controller, inject $filter:

angular.module('ui.bootstrap.demo').controller('ButtonsCtrl', function ($scope, $filter) {

Initialize the filtered array:

ctrl.filtered = [];

And do the filtering in the do change handler:

ctrl.do = function() {
    ctrl.filtered = $filter('filter')(ctrl.collection, { Value: ctrl.radioModel });
    ctrl.active = ctrl.filtered[0];
}