2

Can I have JavaScript functions inside of AngularJS curly braces/notation?

I have tried the code below. If you un-comment my JS functions they don't work.

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="">
  
<p>Some formula: {{ 1+2 }}</p>

<!--

<p>Some function: {{Math.sin(12)}}</p>

<p>Some constructor: {{new Date()}}</p>

-->
  
</div>

Is it possible to unlock/enable?

UPDATE

Okay, in simple {{}} functions can be wrapped into UDFs. But what about functions inside cell template in UI Grid? I still can use simple formulas there, but can't use any functions, even UDFs defined in $scope.

In the sample below, cellTemplateWorks uses simple addition and it works. The template cellTemplateNotWorks uses call to myFunction and not works in template (while works in simple placeholder).

var myApp = angular.module('myApp', ['ui.grid', 'myControllers']);

var myControllers = angular.module('myControllers', []);

myControllers
  .controller('MyController', ['$scope', function ($scope) {
    
    $scope.myData = [{"x": 1}, {"x": 2}, {"x": 3}, {"x": 4}, {"x": 5}];
    
    var cellTemplateWorks = "<div \
       class=\"ngCellText\" ng-class=\"col.colIndex()\"><span ng-cell-text>\
        {{row.entity[col.field]+1}}\
        </span></div>";

    
     var cellTemplateNotWorks = "<div \
        class=\"ngCellText\" ng-class=\"col.colIndex()\"><span ng-cell-text>\
        {{myFunction(row.entity[col.field])}}\
        </span></div>";
    
    $scope.gridOptions = {
            data: 'myData',
            columnDefs: [
//                {field: 'x', displayName: 'x', },
//              {field: 'x', displayName: 'sin(x)', cellTemplate: cellTemplateNotWorks},
              {field: 'x', displayName: 'sin(x)', cellTemplate: cellTemplateWorks},
            ]
        };
    
    $scope.myFunction = function(arg) {
        return Math.sin(arg);
    };
  }]);
.myGrid {
    width: 500px;
    height: 250px;
  }
<link rel="styleSheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.0.7/ui-grid.css"/>

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.0.7/ui-grid.js"></script>

<body ng-app="myApp">
    <div ng-controller="MyController">
      <p>MyFunction does work: {{myFunction(12)}}</p>
      
      <p>MyFunction does not work in UI Grid:
      
        <div ui-grid="gridOptions" class="myGrid"></div>
      
      
      </p>
        
      
    </div>
</body>

1
  • You cannot have functions inside of the curly brackets in AngularJS from my knowledge. Commented Jan 3, 2016 at 8:49

1 Answer 1

2

Quote from the documentation:

Angular Expressions vs. JavaScript Expressions Angular expressions are like JavaScript expressions with the following differences:

Context: JavaScript expressions are evaluated against the global window. In Angular, expressions are evaluated against a scope object.

Forgiving: In JavaScript, trying to evaluate undefined properties generates ReferenceError or TypeError. In Angular, expression evaluation is forgiving to undefined and null.

No Control Flow Statements: You cannot use the following in an Angular expression: conditionals, loops, or exceptions.

No Function Declarations: You cannot declare functions in an Angular expression, even inside ng-init directive.

No RegExp Creation With Literal Notation: You cannot create regular expressions in an Angular expression.

No Object Creation With New Operator: You cannot use new operator in an Angular expression.

No Comma And Void Operators: You cannot use , or void operators in an Angular expression.

Filters: You can use filters within expressions to format data before displaying it.

If you want to run more complex JavaScript code, you should make it a controller method and call the method from your view. If you want to eval() an Angular expression yourself, use the $eval() method.

The last paragraph explains the suggested way to implement this.


UPDATE:

Looks like you are using UI grid. The reason why the expression doesn't work is because this grid has a different scope than the one in which you declared your function. If you want to access the scope of the controller you should use grid.appScope:

 var cellTemplateNotWorks = "<div \
    class=\"ngCellText\" ng-class=\"col.colIndex()\"><span ng-cell-text>\
    {{grid.appScope.myFunction(row.entity[col.field])}}\
    </span></div>";

In this example you can access myFunction inside the template using grid.appScope.

Sign up to request clarification or add additional context in comments.

11 Comments

I don't see any prohibition of using of function calls. So why don't they work?
They don't work because this is not supported. If you want to evaluate some complex expressions that involve function calls, simply wrap this logic in a function on the $scope variable and call this function.
So, you mean calling of standard functions is not supported, while calling of user defined functions is supported?
Yes, exactly, you can call functions defined on the $scope object. For example in your controller you could define a function: $scope.myFunction = function(x) { return Math.sin(x); } and then use this function inside an expression: {{ myFunction(12) }}.
See my update please. I have defined function and it worked. But it worked only in simple {{}}. If I use nested constructions like in UI Grid it still not work. May be it is possible to import parent context or something?
|

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.