How to parse multiple variables via ng-click into a angularjs function - angularjs

I'm new to angularJS and can't seem to figure out how to parse multiple variables from a html button thru an angular JS function.
<html ng-app="">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
</head>
<body ng-controller='CartController'>
<script>
function CartController($scope) {
$scope.addToCart = function(index,product) {
alert(product);
};
}
</script>
<button ng-click="addToCart(2,iPhone);">Add to cart</button>
</body>
</html>
I would expect the second variable (iPhone) would get stored in variable named product but the alert shows its undefined.
What am I doing wrong?

Try using ng-click="addToCart(2,'iPhone');"
What you want is to pass the string 'iPhone', not a property on the $scope called iPhone.
Without the quotes, it will be evaluated against the $scope in CartController. There is no iPhone property on $scope so it will be undefined.
Your original try would work if in CartController you'd have:
$scope.iPhone = "Hello";
The string Hello would be passed to the addToCart function.

Related

$scope.$watch is not triggering when checkbox value changes

How can I express my problem I'm not sure but
$scope.$watch is not triggering when checkbox value changes
in my project.
I've just created the below code snippet in order to show my problem to you but, unfortunately, it is working properly!!
The same approach exists in my project (of course, variable names and function names are different) but it isn't working!!
Do you have any idea about why my code can prevent to work of $scope.$watch in my project? I have tried many things but it is still not working!!
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<input type="checkbox" ng-checked="count==100" ng-true-value="100"
ng-false-value="99999" ng-model="count"> {{caption}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.count = 100;
$scope.$watch("count", function(a,b) {
if ($scope.count==100){
$scope.caption = ' Showing first 100 records';
} else {
$scope.caption = ' Showing all records';
}
});
});
</script>
</body>
</html>
The documentation for ng-checked clearly states that ng-checked should not be used together with ng-model.
From the Docs:
ngChecked
Sets the checked attribute on the element, if the expression inside ngChecked is truthy.
Note that this directive should not be used together with ngModel, as this can lead to unexpected behavior.
— AngularJS ng-checked Directive API Reference

Access form inside controller

Here is my full code:
<html ng-app="myApp">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.js"></script>
</head>
<body >
<div ng-controller="myController">
<form name="myForm">
<input ng-model="option" name="test">
{{myForm.$dirty}}
<button>Save</button>
</form>
</div>
<script>
angular.module('myApp',[]).controller('myController',function($scope){
$scope.option=2;
console.log($scope.myForm);
});
</script>
</body>
</html>
While {{myForm.$dirty}} works, console.log($scope.myForm) returns undefined!!! At the same time if I console.log($scope) I can see myForm as one of its properties!!!! As not to go mad, could someone explain this paradox?
I don't like this solution, but it works. Put a $timeout around the code that you would like to access the form. The $timeout kind of forces the code to wait until the form is fully rendered. (Don't forget to inject $timeout.)
angular.module('myApp',[]).controller('myController',function($scope, $timeout){
$scope.option=2;
$timeout(function() {
console.log($scope.myForm);
}); //Note that you don't need it to actually wait for any amount of time
The reason why you see the form if you console.log($scope) but not when you console.log($scope.myForm), is because the console will evaluate $scope when you expand it. By then, the form has rendered and attached to the scope.
Have you tried to put a watcher on the form ? I'm guessing that the form is simply not yet defined when the controller code is defined.
$scope.$watch('myForm', function(form) {
if(form) {
//check if form is defined
}
});

$compile service in angular returns an array

I am trying to compile a static DOM against scope using the following code
(function(angular) {
var app = angular.module("directiveModule1",[]);
app.controller('testController', ['$scope', function($scope){
$scope.UserName = "afh";
}]);
app.directive("linkFuncDirective",['$compile', function($compile) {
return {
link: function(scope, element, attrs,controller) {
var markUp = "<input type = 'text' ng-model ='UserName'/>{{UserName}}</br>";
var linkFunc = $compile(markUp);
var content = linkFunc(scope);
angular.element(element).html(content);
//angular.element(element).html($compile(markUp)(scope));
}
};
}]);
})(window.angular);
and my html is below
<html>
<head>
<script data-require="angular.js#*" data-semver="1.4.0-beta.5" src="https://code.angularjs.org/1.4.0-beta.5/angular.js"></script>
<script src="directiveWithLinkFunction.js"></script>
</head>
<body ng-App="directiveModule1">
<div ng-controller="testController">
<div link-func-directive></div>
</div>
</body>
</html>
and I get the following o/p
[[object HTMLInputElement], [object HTMLSpanElement], [object HTMLBRElement]]
Trying to understand what was written wrong in code, any help is highly appreciated
The reason behind html is having [[object HTMLInputElement], [object HTMLSpanElement], [object HTMLBRElement]] on view is, You have compiled one line of html using $compile service which returns below as compiled DOM
<input type="text" ng-model="UserName">
<span class="ng-binding ng-scope"></span>
<br class="ng-scope">
So basically it has 3 elements, 1st one is input element, 2nd is span & 3rd is br break tag. So when you try to add it as HTML to page using .html method, jQLite internally takes that object and apply .toString() method to making sure it should accept the string. That's the reason why you are getting [Object...] in the output.
Basically your problem is you are assigning compiled angular DOM html content to the directive element html, which wouldn't make sense.
It should be .append function instead of .html as angular compiled DOM will get injected will have binding enabled.
element.append(content); //would append the DOM with angular compiled DOM.
Why do you want to compile that in the first place ? You can use a simple template for that.
Your code is a little bit mess. Try to clean up first.
give a restrict property to your directive
if you don't have a required field then you don't need a controller parameter
Why don't you just simple use a template for your directive

Angularjs controller nesting

I'm new to angular, I've tried some testing pattern and it's ok with the $scope variable but I can't make it work for a simple controller nesting. (and avoid using the $scope variable, instead I want to use "this")
Here is my sample HTML and javascript :
<!doctype html>
<html ng-app="appTest">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
</head>
<body>
<div ng-controller="FirstController as first">
<div>
First is {{first.text}}
</div>
<div ng-controller="SecondController as second">
Second is {{second.text}}
</div>
</div>
<script>
var app = angular.module("appTest",[]);
function printFirst() {
this.text = "first"
}
function printSecond() {
this.text = "second";
}
app.controller("FirstController",[printFirst]);
app.controller("SecondController",[printSecond]);
</script>
</body>
</html>
In the output html the angular variables inside curly brackets are not replaced and I don't know what's going on. I've tried to install Angular Batarang for debugging but the scope console is empty.
Obviously it's a silly mistake but I don't see where I'm wrong
Ok, the answer has nothing to do with my code, I was just using a too old version of Angularjs (1.0.8).
I moved to the last version 1.3.4 and it works fine.
Access the variable using $scope.text please instead of this.text.

Angular.js: How to reload scope?

I have some markup and loaded controllers.
Then I load some modal window contents by ajax, which is using one of controllers I have defined before. But looks like this controller isn't being used, because he is not required until modal loaded.
Question: How to make controller work when modal loaded? I tryied $scope.$digest(), got error "digest in progress".
index.html
<html data-ng-app="foo">
<head>
<script src="/js/app.js"></script>
</head>
<body>
<div id="modal"></div>
</body>
</html>
js/app.js
!(function(){
function FormCtrl($scope) {
console.log($scope); // never fired
$scope.Submit = function() {
console.log('submit'); // never fired too :C
}
}
angular.module('foo', []).controller('FormCtrl', FormCtrl);
})();
html content loaded by ajax and inserted to #modal
<div data-ng-controller="FormCtrl">
<form name="signup" data-ng-submit="Submit()">
<!-- form data -->
</form>
</div>
SOLUTION:
$.modal().open({
onOpen: function($e) {
$http.get('/views/' + url).success(function(data) {
$compile(data)($scope, function(clonedElem) {
$e.html(clonedElem);
});
// $e.html(data); was used instead of statement above
});
}
});
If you want to inject new DOM elements into existing Anuglar app. You options are to use
ng-include: This has a src property that takes the url from which partial content has to be loaded. AngularJS would internally compile it. One important thing here is that angular will download the template as soon it encounter ng-include in html.
Download and compile DOM manually using the $compile service which is a more involved process.
If your AJAX content contains a controller defined in ng-controller, AngularJS would create it for you.
But in any case, keep in mind the controller script should have been already wired at the initialization\setup phase.

Resources