AngularJS Tables
Learn how to render dynamic, data-driven HTML tables in AngularJS by combining the ng-repeat directive with table rows.
Rendering Tables with ng-repeat
AngularJS builds tables from data, not the other way around. You keep an array of objects on $scope (or on a controller's `this`, referenced as `vm`), place ng-repeat on the <tr> element, and AngularJS clones that row once for every item in the array, keeping the DOM in sync whenever the array changes.
Example
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-app="tableApp" ng-controller="EmployeeController as vm">
<table border="1" cellpadding="6">
<thead>
<tr>
<th>Name</th>
<th>Department</th>
<th>Salary</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="employee in vm.employees">
<td>{{ employee.name }}</td>
<td>{{ employee.department }}</td>
<td>{{ employee.salary | currency }}</td>
</tr>
</tbody>
</table>
</div>
<script>
angular.module('tableApp', [])
.controller('EmployeeController', function() {
var vm = this;
vm.employees = [
{ name: 'Ava Stone', department: 'Engineering', salary: 82000 },
{ name: 'Marcus Lee', department: 'Sales', salary: 61000 },
{ name: 'Priya Nair', department: 'Marketing', salary: 58000 }
];
});
</script>
</body>
</html>Inside an ng-repeat, AngularJS exposes a handful of special variables you can use without declaring them yourself. They are most useful for numbering rows and styling alternating rows in a table.
- Always add a track by expression (for example, track by employee.id) when the array can be re-sorted or filtered, so AngularJS reuses existing DOM rows instead of destroying and rebuilding the whole table.
- Put ng-repeat on the <tr> itself, never on <table> or <tbody>, so each iteration produces exactly one valid table row.
- Combine the filter and orderBy filters directly inside the ng-repeat expression to keep searching and sorting reactive without writing extra watchers.
Example
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-app="tableApp" ng-controller="EmployeeController as vm">
<table>
<tr ng-repeat="employee in vm.employees track by employee.id"
ng-class="{ 'row-even': $even, 'row-odd': $odd }">
<td>{{ $index + 1 }}</td>
<td>{{ employee.name }}</td>
<td ng-if="$first">First row!</td>
</tr>
</table>
<style>
.row-even { background-color: #f4f4f4; }
.row-odd { background-color: #ffffff; }
</style>
</div>
<script>
angular.module('tableApp', [])
.controller('EmployeeController', function() {
var vm = this;
vm.employees = [
{ id: 1, name: 'Ava Stone', department: 'Engineering', salary: 82000 },
{ id: 2, name: 'Marcus Lee', department: 'Sales', salary: 61000 },
{ id: 3, name: 'Priya Nair', department: 'Marketing', salary: 58000 }
];
});
</script>
</body>
</html>Sorting and Filtering Table Data
Because ng-repeat accepts a full AngularJS expression, you can pipe the source array through the built-in filter and orderBy filters right in the template. filter narrows the array down to items matching a search term, and orderBy re-sorts the remaining items by whichever property you point it at.
Example
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
</head>
<body>
<div ng-app="tableApp">
<div ng-controller="EmployeeController as vm">
<input type="text" ng-model="vm.search" placeholder="Search by name...">
<table>
<tr>
<th ng-click="vm.sortKey = 'name'">Name</th>
<th ng-click="vm.sortKey = 'salary'">Salary</th>
</tr>
<tr ng-repeat="employee in vm.employees | filter:vm.search | orderBy:vm.sortKey">
<td>{{ employee.name }}</td>
<td>{{ employee.salary | currency }}</td>
</tr>
</table>
</div>
</div>
<script>
angular.module('tableApp', [])
.controller('EmployeeController', function() {
var vm = this;
vm.employees = [
{ name: 'Ava Stone', department: 'Engineering', salary: 82000 },
{ name: 'Marcus Lee', department: 'Sales', salary: 61000 },
{ name: 'Priya Nair', department: 'Marketing', salary: 58000 }
];
});
</script>
</body>
</html>Exercise: AngularJS Tables
How are table rows typically generated from an array of data?