Mthandazo Dube
Mthandazo Dube

Reputation: 5

Wrong array item after using orderby filter AngularJS

I have an app that works well displaying a list of students. When you click on each name, it displays more info about that particular student. However, if I change the order of names through select options or search, wrong student info is displayed. Here is my view:

<input type="text" ng-model="expression" placeholder="Search Student" />
<div class="select">
<span>Sort By: &nbsp;</span>
<select ng-model="order" ng-show="students.length > 0">
    <option selected value="name">Name A-Z</option>
    <option value="-name">Name Z-A</option>
    <option value="room">Room (first to last)</option>
    <option value="-room">Room (last to first)</option>           
</select>
</div>
<div ng-repeat="student in students | orderBy: order | filter:expression">        

<div class="info">
    <div class="img">
        <img ng-src="{{student.image}}">
    </div>
    <h2 style="color: #007acc;"> Student Details For:</h2>
    <hr>
    <h2>{{student.name}}</h2>
    <a ng-href="#!/students/{{$index}}"><button>View Student 
    Details</button></a>
    </div>
    </div>

Here is my Js:

var data = [
{
    name: "Andrea Toe",
    sex: "Female",
    room: 12,
    cell: "076 861 6184",
    image: "images/female.jpg",
    checkin: "June 2016"
},
{
    name: "John Doe",
    sex: "Female",
    room: 3,          
    cell: "063 961 7190",
    image: "images/lebo.jpg",
    checkin: "01 Feb 2018"      
},
{
    name: "James Drew",
    sex: "Male",
    room: 1,
    cell: "076 910 3069",
    image: "images/male.jpeg",
    checkin: "01 Feb 2018"
 }
];
app.controller("studentsCtrl", function($scope){
$scope.students = data;
});
app.controller('studentInfoCtrl', ['$scope', '$routeParams', 
function($scope, $routeParams) {
  $scope.info = data[$routeParams.id];
}]);

What should I do to get it to display correct info even after using search filter or reordering using oderBy?

Upvotes: 0

Views: 48

Answers (2)

Aagam Jain
Aagam Jain

Reputation: 1546

Searching and sorting are working fine for me:

var data = [{
    id: 1,
    name: "Andrea Toe",
    sex: "Female",
    room: 12,
    cell: "076 861 6184",
    image: "images/female.jpg",
    checkin: "June 2016"
  },
  {
    id: 2,
    name: "John Doe",
    sex: "Female",
    room: 3,
    cell: "063 961 7190",
    image: "images/lebo.jpg",
    checkin: "01 Feb 2018"
  },
  {
    id: 3,
    name: "James Drew",
    sex: "Male",
    room: 1,
    cell: "076 910 3069",
    image: "images/male.jpeg",
    checkin: "01 Feb 2018"
  }
];
app = angular.module("myapp", []);
app.controller("studentsCtrl", function($scope) {
  $scope.students = data;
});
app.controller('studentInfoCtrl', ['$scope', '$routeParams',
  function($scope, $routeParams) {
    $scope.info = data.filter(function(d){
      return d.id == $routeParams.id;
    })[0];
  }
]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.1/angular.min.js"></script>

<div ng-app="myapp" ng-controller="studentsCtrl">

  <input type="text" ng-model="expression" placeholder="Search Student" />
  <div class="select">
    <span>Sort By: &nbsp;</span>
    <select ng-model="order" ng-show="students.length > 0">
      <option selected value="name">Name A-Z</option>
      <option value="-name">Name Z-A</option>
      <option value="room">Room (first to last)</option>
      <option value="-room">Room (last to first)</option>
    </select>
  </div>
  <div ng-repeat="student in students | filter:expression | orderBy: order ">

    <div class="info">
      <!-- <div class="img">
        <img ng-src="{{student.image}}">
      </div> -->
      <h2 style="color: #007acc;"> Student Details For:</h2>
      <hr>
      <h2>{{student.name}}</h2>
      <a ng-href="#!/students/{{student.id}}"><button>View Student 
    Details</button></a>
    </div>
  </div>
</div>

Upvotes: 0

ccjmne
ccjmne

Reputation: 9618

It is because, when creating the link to the "student details", you use the $index scope variable.

This $index is introduced by the ng-repeat directive and will represent the:

iterator offset of the repeated element (0..length-1)

(from the documentation linked here)

In short, the $index you use to uniquely identify a student when building the corresponding link to their details page depends entirely on its position in the page. It does not at all identify the resource itself!

What you could do is have an id property assigned to each student along with their name, sex etc., like so:

var data = [{
    id: 0,
    name: "Andrea Toe",
}, {
    id: 1,
    name: "John Doe",
}, {
    id: 2,
    name: "James Drew",
}];

And simply refer to that newly introduced property in the urls you create!

<a ng-href="#!/students/{{ student.id }}"><button>View Student Details</button></a>

Upvotes: 1

Related Questions