Function is not defined error in Angular.js - javascript

When I use this script:
<script>
function TestClick() {
alert("Test clic");
}
</script>
With this HTML code:
<div>
<input name="BtnAddNew" type="button" value="Load all OPCVM" onclick="TestClick()" />
</div>
It works.
But once I try to put everything inside a controller :
<head>
<meta name="viewport" content="width=device-width" />
<title>PetitsTests</title>
<script src="~/Scripts/jquery-1.10.2.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="~/Scripts/angular.js"></script>
<script>
var myApp= angular.module("myApp", []);
myApp.controller('OPCVMViewModel', function ($scope, $http) {
function TestClick() {
alert("test clic");
}
});
</script>
</head>
<body ng-app="myApp">
<div ng-controller="OPCVMViewModel">
<input name="BtnAddNew" type="button" value="Load all OPCVM" onclick="TestClick()" />
</div>
</body>
Then I get a "TestClick is not defined" error...

In your controller, try
$scope.TestClick = function(){ alert("test click"); };
And then in the button HTML:
type="button" ng-click="TestClick()"
In short, functions needs to be defined in scope. and use ng-click to call the function.

Example from the official docs:
var myApp = angular.module('myApp',[]);
myApp.controller('DoubleController', ['$scope', function($scope) {
$scope.double = function(value) { return value * 2; };
}]);
In short, you must attach whatever functions or properties you declare inside your controller to $scope in order to make them avaialbe to your template/view:
var app = angular.module("myApp", []);
app.controller('OPCVMViewModel', function ($scope, $http) {
function TestClick() {
alert('Test click');
}
$scope.TestClick = TestClick;
// or:
$scope.TestClick = function() {
alert('Test click');
};
});
Also, as JohnMoe has pointed out in the comments, there are other issues in your code.
First of, you should not use onclick, but ng-click. You can find the full list of ng directives here.
Moreover, the controller as syntax is the recommended way to go as from Angular 1.2, even though it will work without it.
Instead of writing something like:
app.controller('FooController', function ($scope) {
$scope.property = 'Foo';
});
You replace $scope for this, and now you don't need to inject $scope and have a nicer class-like looking controller:
app.controller('FooController', function () {
this.property = 'Foo';
});
Your templete will look like this:
<div ng-controller="FooController as vm">
{{ vm.property }}
</div>
If later on you decide to create a directive, it will look something like this:
app.controller('FooController', function () {
this.property = 'Foo';
});
app.directive('fooDirective', function () {
return {
restrict: 'E',
controller: 'FooController',
controllerAs: 'vm',
template: '{{ vm.property }}'
};
});
Also, you could use proper ES6 classes with a transpiler. Take a look at this if you are interested

Related

Calling anonymous method recursively in angular controller method

I want to send ajax requests at regular intervals from the angular controller method. for that i have written code like below.
var mainApp = angular.module('myapp',[]);
mainApp.controller('controller', function($scope,$http,$window,$timeout) {
$('#radioBtn a').on('click', function(){
$http({
method:,
url:,
params:{parameters}
}).then(function(success){
},function(error){
});
$timeout(function(){
//how to call the anonymous function passed to $('#radioBtn a').on() here.
},30000);
});
I am not getting how to call the anonymous method from timeout function. Using this() is failing.
First off: Don't bind to element clicks like that, use the ng-click directive - in fact, just don't even load jQuery in your application, in 99% cases you're better off without it.
Second: Use angular's $interval service. Check the code sample below.
angular.module('app', [])
.controller('ctrl', function($scope, $interval) {
$scope.numbers = [];
$scope.startInterval = function() {
$scope.interval = $interval(function() {
$scope.numbers.push($scope.numbers.length);
}, 1000)
}
})
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.6.0" data-semver="1.6.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="app" ng-controller="ctrl">
<button ng-if="!interval" ng-click="startInterval()">Start polling</button>
<div ng-repeat="number in numbers">
{{number}}
</div>
</body>
</html>
try this way.
var mainApp = angular.module('myapp',[]);
mainApp.controller('controller', function($scope,$http,$window,$interval) {
$('#radioBtn a').on('click', function(){
$interval(function(){
$http({
method:,
url:,
params:{parameters}
}).then(function(success){
},function(error){
});
},30000);
});

Converting jquery function to angularjs

I have this function in jQuery but I'm facing problem converting that into angularJs function:
$('p').each(function() {
$(this).html($(this).text().split(/([\.\?!])(?= )/).map(
function(v){return '<span class=sentence>'+v+'</span>'}
));
It would really help if someone could explain to me how one would implement these lines of code in angularJs
Thanks in advance guys
easiest way is just splitting into an array and binding that to your controller.
More in depth way would be to roll your own custom directive, let me know if you want to see a way with a directive
<html ng-app="MyCoolApp">
<head>
</head>
<body ng-controller="MyCoolController">
<p ng-repeat="text in Array">
{{text}}
</P>
</body>
</html>
<script type="text/javascript">
var myApp = angular.module('MyCoolApp',[]);
myApp.controller('MyCoolController', ['$scope', function($scope) {
var dataSource = [];//your data split
$scope.Array = dataSource;
}]);
</script>
edit
Updated to use custom directive. YOu will need to tweak the regEx to split properly plunkr example
split.html
<div>
<textarea ng-model="input"></textarea>
<button ng-click="Process(input)">Process</button>
<p>
<span style="border:1px solid red" ng-repeat="text in Output track by $index">
{{text}}
</span>
</p>
</div>
script.js
(function(angular) {
'use strict';
angular.module('splitExample', [])
.directive('mySplit', function() {
return {
templateUrl: 'split.html',
controller: function($scope){
$scope.Process = function(text){
$scope.Output = text.split(/([\.\?!])(?= )/);
console.log(text)
}
}
};
})
})(window.angular);
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-directive-tabs-production</title>
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="splitExample">
<my-split>
</my-split>
</body>
</html>
You need to write a directive for it, DOM Manipulation is only allowed in directives in the link function otherwise it is a very bad practice. Here is the code inside link function of directive.
link: function (scope, element, attributes) {
var el= $(element);
el.find('p').each(function(){
el.html(el.text().split(/([\.\?!])(?= )/).map(
function(value){
return '<span class=sentence>'+value+'</span>'
}
));
});
}
Hope it helps you, I am unable to know actually what you are trying to do.. otherwise i would have helped you with full solution and proper directive approach, for any further assistance let me know. Thanks.
Just giving my suggestion : JQuery approach is incompatible with AngularJS.
Updated directive as per your requirement:
angular.module('yourAppModuleName').directive('contentClick', ['$timeout', function($timeout) {
return {
restrict: 'A',
require: 'ngModel',
scope: {
contentEditable: '=contentEditable'
},
link: function(scope, element, attributes) {
scope.$watch(attributes.contentEditable, function(value) {
if (value === undefined)
return;
scope.contentEditable = attributes.contentEditable;
});
if(scope.contentEditable == 'true') {
scope.$watch(attributes.ngModel, function(value) {
if (value === undefined)
return;
value.split(/([\.\?!])(?= )/).map(
function(v){
return '<span onclick="myFunction(this)" >'+v+'</span>'
}
);
});
}
//without timeout
//function myFunction(x) {
// x.style.background="#000000";
//}
//with timeout
function myFunction(x) {
$timeout(function() {
x.style.background = "green";
}, 10000);
}
}
};
}]);
HTML:
<div contentEditable="isEditable" style="cursor:pointer" ng-model="content" content-click></div>
Controller:
yourAppModuleName.controller('myController', ['$scope', function($scope) {
$scope.isEditable = true;
$scope.content;
}]);

Ways to declare Function in AngularJS Controller (controllerAs approach)

I use controller as approach instead of $scope. I have some problems with method calling from HTML. So, the question is that, how many ways exist in declare and call functions in this approach.
first: (If I want to do s.th. at first)
var vm= this ;
vm.dataOne=[];
function funcOne() {
myService.serviceFunc()
.then(function (response) {
vm.dataOne= response.data;
});
};
function activate() {
funcOne();
}
activate();
second: (If I want to initialize a variable based on a function returned value )
vm.dataTwo = function () {
doSomeThing();
}
Is there any way, too?
How should define a function in controller
which will be called from HTML, as
ng-click = "ctrl.dataTwo()";
Functions the way you've defined are private:
function functionOne() {
}; // Just function body, no need of semicolon
These are known as function declarations. Currently, they are only accessible within your controller.
To be able to call them, attach them to the controller so they become controller variables:
vm.functionOne = functionOne;
An advantage of this approach is that you can define functions after actually calling them, as opposed to how you do with $scope or $this. They are recognized via hoisting, and called.
About your initializing a returned value from a function, just call it:
vm.someVariable = someFunction();
Some references:
var functionName = function() {} vs function functionName() {}
Private Members in JavaScript
Angular Function Declarations, Function Expressions, and Readable Code
Angular Style Guide
First way using ng-controller="cntrl as vm" syntax:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
angular.module('MyApp', [])
.controller('MyCntrl', function($scope) {
var vm = this;
vm.name = 'Custom Directive';
});
</script>
<body>
<div ng-app="MyApp" ng-controller="MyCntrl as vm">
{{vm.name}}
</div>
</body>
</html>
Second way using controllerAs as one of the attribute of directive:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
angular.module('MyApp', [])
.directive('customDir', function() {
return {
restrict: 'EA',
template: '<div>{{vm.name}}</div>',
controller: function(){
var vm = this;
vm.name = 'Custom Directive';
},
controllerAs: 'vm'
}
});
</script>
<body>
<div ng-app="MyApp">
<div custom-dir></div>
</div>
</body>
</html>
Way to calling a function with "controller as" syntax which is defined in controller but called in html:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
angular.module('MyApp', [])
.controller('MyCntrl', function($scope) {
var vm = this;
vm.name = 'Custom Directive';
vm.someFunction = function() {
vm.name = 'Button is Clicked!!!';
};
});
</script>
<body>
<div ng-app="MyApp" ng-controller="MyCntrl as vm">
{{vm.name}}
<input type='button' ng-click="vm.someFunction()" value="Click" />
</div>
</body>
</html>
Other way, use function as constructor and add functionality to prototype
function Ctrl($window) {
this.$window = $window;
}
Ctrl.inject = ['$window']
Ctrl.prototype.click = function() {
this.$window.alert('clicked')
}
angular.module('app', [])
.controller('ctrl', Ctrl)
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app' ng-controller='ctrl as c'>
<button ng-click='c.click()'>Click me!</button>
</div>

AngularJs: Argument is not a function got undefined

I started learning AngularJs so I started off this way by creating a view, service file and controller file separately as shown below:
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="ServicesTut.js"></script>
<script src="ControllerTut.js"></script>
</head>
<body>
<div class="container">
<div ng-controller="CalculatorController">
Enter a number:
<input type="number" ng-model="number">
<button ng-click="findSquare()">Square</button>
<div>{{answer}}</div>
</div>
</div>
</body>
</html>
This is my service file --- ServicesTut.js"
var CalculatorService = angular.module('CalculatorService', [])
app.service('Calculator', function () {
this.square = function (a) { return a*a};
});
This is my controller file --- ControllerTut.js
var myApp = angular.module('myApp', ['CalculatorService']);
app.controller('CalculatorController', function ($scope, Calculator) {
$scope.findSquare = function () {
$scope.answer = Calculator.square($scope.number);
}
});
On launching the code on my browser I get the following error message:
Error: Argument 'CalculatorController' is not a function, got undefined
Please assist me!
In your ServicesTut.js you should be using CalculatorService variable instead of app, which is why service doesn't get registered in the CalculatorService module.
var CalculatorService = angular.module('CalculatorService', [])
app.service('Calculator', function () {
should be
var CalculatorService = angular.module('CalculatorService', [])
CalculatorService.service('Calculator', function () {
And in controller same thing repeated again, use myApp instead of app while registering controller.
var myApp = angular.module('myApp', ['CalculatorService']);
myApp.controller('CalculatorController', function ($scope, Calculator) {

angularjs, Scope not updating across functions - with ngTouch

I have a controller with such:
$scope.myVar = 0;
$scope.back = function () {
$scope.myVar--;
};
$scope.next = function () {
$scope.myVar++;
};
If next() (with ngClick) is called 3 times, we get:
//1
//2
//3
but if back() (with ngSwipeLeft) is called it returns
//-1
when I'm obviously expecting
//2
What am I missing here?
update: including ngTouch details - this seems to be the problem.. ngTouch is included.
When I watch the myVar value - its like it exists twice - one with the ngSwipeLeft call, and one with the ngClick call
Your snippet looks fine to me. You need to provide more code, error might be somewhere else. Look at the code below.
<!doctype html>
<html ng-app="myapp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-touch.min.js"></script>
<script>
var app = angular.module('myapp',['ngTouch']);
var controller = app.controller('mycontroller', ['$scope',function($scope){
$scope.myVar = 0;
$scope.back = function () {
$scope.myVar--;
};
$scope.next = function () {
$scope.myVar++;
};
}]);
</script>
</head>
<body ng-controller="mycontroller">
<div>
<h1>MyVar: {{myVar}}!</h1>
<input type="button" value="back" ng-click="back()"/>
<input type="button" value="next" ng-click="next()"/>
</div>
</body>
</html>
Ok, so I've figured out my problem - I wasn't providing enough detail in the question - but if someone runs into something similar in the future, heres what was going on:
I was declaring my controller with ng-controller="myCtrl" in the templates, but also using routing, where I declared my controller like:
$routeProvider.when('/', {
templateUrl: 'myUrl.html',
controller: 'myCtrl'
});
This was instantiating the controller twice, and obviously causing problems (although that seemed to the only one to surface for now).
Removing the controller definition from the routing or the view did the trick.
need to see your html not sure about your problem, here is a sample working code,
<div ng-app="myapp">
<div ng-controller="IncDecController">
<span>current value is {{myVar}}</span>
<img src="https://angularjs.org/img/AngularJS-large.png" ng-swipe-left="back()"></img>
<button ng-click="next()">next</button>
</div>
</div>
script:
angular.module('myapp', ['ngTouch'])
.controller('IncDecController', ['$scope', function ($scope) {
$scope.myVar = 0;
$scope.back = function () {
$scope.myVar--;
};
$scope.next = function () {
$scope.myVar++;
};
}])

Categories

Resources