I'm using the MEAN stack and jade. I'm running into a problem with AngularJS using ng-repeat, ng-click, and orderby to sort columns in a table. It works fine as long as there is no space in the property name that is used for orderBy. The property name I'm having trouble with is "To Do".
I get this error in Chrome when I click the table header labeled "To Do":
Error: Syntax Error: Token 'Do' is an unexpected token at column 4 of the expression [To Do] starting at [Do].
I have seen a couple other posts about trouble with accessing properties with a space. My issue is similar but I cannot get their solutions to work.
Jade: (This is how I have set up ng-click, orderBy, and ng-repeat. It works fine unless there is a space in the column)
table
caption {{collectionName}}
thead
tr
th(ng-repeat="column in columns" ng-click="setPredicate(column);")
{{column}}
tbody
tr(ng-repeat="row in rows | orderBy:predicate:reverse")
td(ng-repeat="column in columns")
{{row[column]}}
Controllers.JS: (This is how Angular receives data for columns and rows. Also how ng-click changes the orderBy predicate)
$http.get('/api/collection/' + $routeParams.collectionName)
.success(function(data){
$scope.collection = data;
$scope.columns = data.columns;
$scope.rows = data.rows;
console.log(data);
});
$scope.setPredicate = function(column){
if (column === "To Do"){
var keys = Object.keys($scope.rows[0])
$scope.predicate = keys[1];
// $scope.predicate = "To Do";
// $scope.predicate = column[$scope.columns];
}else{
$scope.predicate = column;
}
$scope.reverse = !$scope.reverse;
}
In the above code keys is equal to [ "_id", "To Do", "description", "due", "link", "$$hashKey"].
keys[1] is "To Do", which still does not work for the orderBy predicate. I tried other variations like the two commented out attempts above.
NodeJS index.JS: (This is how the columns array and the rows are sent to Angular after retrieving documents from MongoDB.)
router.get('/api/collection/:collectionName', function(req, res){
collectionProvider.findCollection(req.param('collectionName'), function(error, documents){
var keys;
if(documents[0]){
keys = Object.keys(documents[0]);
remove(keys,'_id');
}
res.json({
columns: keys,
title: req.param('collectionName'),
rows:documents,
collectionName: req.param('collectionName')
});
});
});
To summarize, the column headings in my table are named after the property that represents the data in the column. I don't know which table will be pulled up or what columns it will have so node checks all the properties of the first record and sends an array of property names to $scope.columns. I use a predicate to switch the orderBy sorting to whichever column in $scope.columns gets clicked.
This is my first angular app. I originally expected to be able to use ng-click="predicate=column" in the Jade, but I was surprised to find out it did not work. That's why I'm sending to a controller function. I do not know if I'm going about this whole process the correct Angular way.