Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Evaluate string in dot notation to get the corresponding value from an object in the view

Really hoping someone can help me with a problem I've had a couple of times recently.

Let's say I have two objects in AngularJS.

$scope.fields = ['info.name', 'info.category', 'rate.health']

$scope.rows = [{
    info: { name: "Apple", category: "Fruit"},
    rate: { health: 100, ignored: true}
},{
    info: { name: "Orange", category: "Fruit"},
    rate: { health: 100, ignored: true}
},{
    info: { name: "Snickers", category: "Sweet"},
    rate: { health: 0, ignored: true}
}]

I would then like to display a table in a view that shows only the fields in the $scope.fields. This would be super easy if the table was flat, and I know I could flatten it using JavaScript, but there must be a way to do this by converting the dot notation to the path.

I have added a JSFiddle to demonstrate the problem I'm having:

JSFiddle: http://jsfiddle.net/7dyqw4ve/1/

I have also tried doing something as suggested below, but the problem is its terrible practice to use functions in the view: Convert JavaScript string in dot notation into an object reference

If anyone has any ideas I would greatly appreciate it.

like image 672
Mark Avatar asked Mar 11 '15 00:03

Mark


1 Answers

In this case you can make use of angular's built in evaluator exposed via the property $eval on the scope (not the vanilla eval) to evaluate any angular expression (not for evaluating javascript as eval does). Angular internally uses this to evaluate the expression on the scope while resolving the bindings.

Example:-

{{$eval(field, row)}}

You could do:-

 <th ng-repeat="field in fields">{{$eval(field, row)}}</th>

or wrap the logic in the controller and expose it via a method on the scope.

  <th ng-repeat="field in fields">{{getValue(field, row)}}</th>

and

$scope.getValue = function(exp, row){
    return $scope.$eval(exp, row);
}

Demo

You could as well use $parse (inject $parse) service.

$scope.getValue = function(exp, row){
    return $parse(exp)(row);
}

and

<th ng-repeat="field in fields">{{getValue(field, row)}}</th>

Demo

like image 54
PSL Avatar answered Oct 11 '22 22:10

PSL