$compile containing function as attribute value - angularjs

I'm facing one issue with $compile.
The code I've written is very big hence I'm create one small example to replicate this issue.
Suppose I've a button in my page.
When user clicks on that button, one more button will be created which will be having ng-click method as shown below:
$scope.showAlert = function(){
alert('pass');
}
$scope.createExample = function() {
var button = '<button type="button" ng-click="' + $scope.showAlert + '()">click</button>';
angular.element(document.body).append($compile(button)($scope));
}
HTML: <button type="button" ng-click="createExample()">test</button>
When user clicks on button, createExample() method will be invoked. This method will create another button which will be having ng-click. This ng-clicks holds a method which give alert.
I'm getting error below:
Error: Syntax Error: Token '{' is an unexpected token at column 12 of the expression [function (){
alert('pass');
}()] starting at [{
alert('pass');
}()].
at Error (native)
at throwError (https://code.angularjs.org/angular-1.0.1.js:5830:11)
at parser (https://code.angularjs.org/angular-1.0.1.js:5824:5)
at https://code.angularjs.org/angular-1.0.1.js:6387:29
at https://code.angularjs.org/angular-1.0.1.js:12493:18
at nodeLinkFn (https://code.angularjs.org/angular-1.0.1.js:4223:13)
at compositeLinkFn (https://code.angularjs.org/angular-1.0.1.js:3838:14)
at https://code.angularjs.org/angular-1.0.1.js:3750:30
at Object.$scope.createExample (http://fiddle.jshell.net/JKBbV/751/show/:44:65)
at https://code.angularjs.org/angular-1.0.1.js:6129:19 <button type="button" ng-click="function (){
alert('pass');
}()" class="ng-scope">
$compile is the only option i have.
How to make this work??
JSFiddle here

ng-click takes the handler name to execute, here you are evaluating the method content.
Correct code would simply be :
$scope.showAlert = function(){
alert('pass');
}
$scope.createExample = function() {
var button = '<button type="button" ng-click="showAlert()">click</button>';
angular.element(document.body).append($compile(button)($scope));
}

Related

How to change the name of the button? Ng-show, ng-if, ng-click does not work?

I am trying to change the name of the button from Hold Payment to Unhold Payment, it should first check the status of the checkstatus.is_holdpayment and then execute the function userhold_payment(). I tried various things, ng-show, ng-if but the name of the button does not change on click. On click it should go, Hold, Unhold, Hold, Unhold and also execute the same function, userhold_payment(). I want to change the name of the button using AngularJS. What is the mistake. Here is the main.html
<div ng-init="check_status()">
<button type="button" ng-if="checkstatus.is_hold_payment" ng-click="userhold_payment();" class="btn-success btn-lg hold_payment_html" style="margin-top:7px; font-size:16px">Hold</button>
<button type="button" ng-if="!checkstatus.is_hold_payment" ng-click="userhold_payment();" class="btn-success btn-lg hold_payment_html" style="margin-top:7px; font-size:16px">UnHold</button>
</div>
Here is the Controller for the function.
$scope.userhold_payment = function() {
$http.get('http://localhost/ngaffiliate/api/payment/change_hold_payment_status')
.then(function(response) {
console.log('I called');
$scope.userhold = response.data;
console.log($scope.userhold.is_hold_payment);
});
};
//this will call when ever your controller reinstance
($scope.check_status = function() {
$http.get('http://localhost/ngaffiliate/api/payment/check_payment_status')
.then(function(response) {
console.log('I called now')
$scope.checkstatus = response.data;
// console.log(response);
console.log($scope.checkstatus.is_hold_payment);
if($scope.checkstatus.is_hold_payment=="0")
$scope.checkstatus.is_hold_payment = true;
else($scope.checkstatus.is_hold_payment=="1")
$scope.checkstatus.is_hold_payment = false;
$scope.checkstatus.is_hold_payment =!$scope.checkstatus.is_hold_payment;
console.log($scope.checkstatus.is_hold_payment);
});
})();
As I already mentioned in my comment, you should probably call $scope.check_status() in your $scope.userhold_payment() function, since the function doesn't normally change the value of the $scope.checkstatus.is_hold_payment variable. I also removed the line where you reversed the variable's value.
Plunker here to demonstrate: https://plnkr.co/edit/SWpdHGaNWIkyIWSvHyUU?p=preview
Try using this:
<button type="button" ng-click="userhold_payment();" class="btn-success btn-lg hold_payment_html" style="margin-top:7px; font-size:16px">{{checkstatus.is_hold_payment ?? "Hold": "Unhold"}}</button>

Add a function to html string in link layer of directive

I got this directive which renders a list of objects. this objects got it's own function, i wanna bind it to a button. So i run over my items.In my objects value, i got a prop called Action which value is a function. i then try to add it to the html string, then i say it should be trusted as html. like shown below
angular.forEach(data.Items, function (value, key) {
var buttonsCode = "";
buttonsCode += '<div class="btn btn-sm" ng-click="' + value.Action + '">Test</div>';
value["buttons"] = $sce.trustAsHtml(buttonsCode);
});
but when i try to run it, it looks like this
<div class="btn btn-sm" ng-click="function () {
alert("test of funtion"); }">Test</div>
Anyone know how i can do this?

ng-click directive not working on button

html
<button class="btn btn-primary" ng-click="tasks.passivate()">
Passivate <i class="fa fa-spinner fa-spin" ng-if="tasks.passivating"></i>
</button>
task.controller
function passivate() {
console.log('passivate');
vm.passivating = true;
return taskService
.passivate(vm.task.id)
.then(function (task) {
vm.passivating = false;
})
.catch(alertError);
}
The button does not work, passivate does not appear in the console.
When referencing something from the controller in the view, you have to use the $scope. Your function definition should be:
$scope.tasks.passivate = function() {
//...
}
your button, I believe is part of the view which is now bound to a controller. The controller creates a scope object which actually glues your view and the controller. So if you want to invoke a function from the view it should have the scope reference. Hence $scope should be used:-
$scope.tasks.passivate = function(){
//----your logic goes here.
}
Its good to see that you are using tasks.passivate as it will save your from prototypal inheritance. To know more:- Click here

two-way data binding not working for data-ng-disabled

How can I can get btnDisabled to change the data-ng-disabled in the immediate function scope but inside my ajax success scope nothing is playing nicely. How to I get my button to disable?
JS
.controller('CouponCtrl', function($http, $scope) {
$scope.btnDisabled = false;
// $scope.btnDisabled = true; // this works fine too
$http.jsonp("someurl?_jsonp=JSON_CALLBACK").success(function(){
$scope.btnDisabled = true; // does not work
console.log("I see this so why doesn't my button disable?");
// $scope.$digest(); // tried this too but I'm told digest is already running
}
}
HTML
<button data-ng-disabled="{{ btnDisabled }}" class="button button-block green">redeem coupon</button>
NOTE
I've noticed that none of my two-way data binding works when I update a variable via the ajax success scope. Is there a way to overcome that?
ngDisabled expects an expression, not a string (interpolation always outputs string values):
<button data-ng-disabled="btnDisabled"
class="button button-block green">redeem coupon</button>
Working Plunker
Change
data-ng-disabled
to
ng-disabled

Add an event on ng-show

i'm not an angular master and i try to do something.
Suppose a fonctionality like "i like / i dislike".
When you're on an article, you can click on the "i like" button. If you already liked the article, this button is hidden and the "i don't like anymore" appears.
<button ng-hide="like" class="btn btn-success btn-xs pull-right" ng-click="iLike()">I like</button>
<button ng-show="like" class="btn btn-danger btn-xs pull-right" ng-click="notLike()">Don't like anymore</button>
Everything work as expected when i reload the page but not on click action.
Basically my iLike function looks like and i think miss behavior comes from a missing return or an event to fire :(
$scope.iLike = function(){
##hereIDoAnAPICalls##, function(){
$scope.like = false;
}, function(){
$scope.like = true;
}
}
Try to wrap scope variable assignment into apply, I think it could help since API call is probably asynchronous and click event is invoked from outside of angular
$scope.iLike = function() {
APIcall.then(function () {
$scope.$apply(function() {
$scope.like = false;
});
}, function () {...the same...});
};

Resources