Richard Hamilton
Richard Hamilton

Reputation: 26444

ng-click - Using functions for property values

I'm creating a calculator app in AngularJS, but am having trouble with ng-repeat and ng-click.

<div class="col-md-3">
  <button ng-repeat="op in operations" name="btn{{ op.name }}"
          value="{{ op.symbol }}" class="operationbutton" 
          ng-click="{{ op.function }}"> {{ op.symbol }}
  </button>
</div>

In my app.js, inside my controller, I have an operations variable tied to $scope.

$scope.operations = [
    { "symbol": "+", "name": "add", "function": "add()" },
    { "symbol": "-", "name": "subtract", "function": "subtract()" },
    { "symbol": "*", "name": "multiply", "function": "multiply()" },
    { "symbol": "/", "name": "divide", "function": "divide()" }
];

I've tried taking the quotation marks off the function names, but it turns out that JavaScript object values must contain strings.

I could do something like this

ng-click="{{ op.name === 'add' ? add() : op.name === 'subtract' ? subtract()
: op.name === 'multiply' ? multiply() : op.name === 'divide' ? divide() : multiply()}}"

But that seems like a terrible practice. Is there any way I can improve this, so I can call a function based on the operation?

Upvotes: 0

Views: 95

Answers (3)

Abdullah Rasheed
Abdullah Rasheed

Reputation: 3752

You could possibly reorganize your code this way. You controller you would define your functions add to the $scope object.

var add = function() {
 //code here
 }    

var subtract = function() {
 //coder her
 }     
$scope.operations= [
    { "name" : "add", "func" : add},
    { "name" : "subtract", "func" : subtract},
    ]

In the html you would do this reference them this way

  <div class="col-md-3">
  <button ng-repeat="op in operations" ng-click="op.func()"> {{ op.symbol }}
  </button>
  </div>

Upvotes: 1

New Dev
New Dev

Reputation: 49610

The best approach is to assign the actual function, rather than a string expression of function invocation, to each op:

function add(){
  // whatever you do now
}

// same for other functions
function subtract(){}
function multiply(){}
function divide(){}

$scope.operations = [
    { "symbol": "+", "name": "add", "function": add },
    { "symbol": "-", "name": "subtract", "function": subtract },
    { "symbol": "*", "name": "multiply", "function": multiply },
    { "symbol": "/", "name": "divide", "function": divide }
];

And ng-click becomes:

<button ng-repeat="op in operations"  
        ng-click="op.function()"> 
  {{ op.symbol }}
</button>

Upvotes: 4

Praveen Prasannan
Praveen Prasannan

Reputation: 7133

$scope.operations = [
    { "symbol": "+", "name": "add"},
    { "symbol": "-", "name": "subtract"},
    { "symbol": "*", "name": "multiply"},
    { "symbol": "/", "name": "divide"}
];

<div class="col-md-3">
  <button ng-repeat="op in operations" name="btn{{ op.name }}"
          value="{{ op.symbol }}" class="operationbutton" 
          ng-click="op.Operationfunction(op.name)"> {{ op.symbol }}
  </button>
</div>

$scope.Operationfunction = function(operation){
switch(operation)
 case 'add':
  add();
  break;
 case 'multiply':
  multiply();
  break;
....
};

Upvotes: 0

Related Questions