0

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?

2 Answers 2

1

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>
Sign up to request clarification or add additional context in comments.

1 Comment

Ok, I will. Is there a way of adding id: dynamically in the array because if I use a delete function and remove an item, then it starts showing wrong student info again? $scope.remove=function(item){ var index=$scope.students.indexOf(item) $scope.students.splice(index,1); };
0

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>

6 Comments

My question is not on filtering or sorting. That works fine. My problem is that after sorting or filtering, when you click on a student name, it displays info of a wrong student. Eg. when you search for John Doe and click on his name, it displays info for Andrea Toe instead.
Use student.id for routing instead of $index. because it changes how your ng-repeat data is rendered and it do not change data in your actual array.
If I replace $index with student.id like this: <a ng-href="#!/students/{{student.id}}"><button>View Student Details</button></a> it stops working, it doesn't route.
have you added id in your student data. also on routed page to retrieve student from data use filter as in code.
Is there a way of adding id: dynamically in the array because if I use a delete function and remove an item, then it starts showing wrong student info again? Here is my delete function: $scope.remove=function(item){ var index=$scope.students.indexOf(item) $scope.students.splice(index,1); };
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.