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) {
Related
I am using Angularjs in asp.net core website which has jquery as well. AngularJS is being used for a small part of the website. Below is the AngularJS HTML
(function () {
var app = angular.module('dashBoardApp', []);
console.log(app);
var xx = app.controller('dashBoardController', ['$scope', function ($scope) {
$scope.value = 'Test';
}]);
})();
<div ng-app="dashBoardApp">
<div ng-controller="dashBoardController">
<p>{{5+5}}</p>
</div>
</div>
I must be doing something stupid. But unable to figure out.
You need to add a reference to the angular lib
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
Then it works like a charm
(function () {
var app = angular.module('dashBoardApp', []);
console.log(app);
var xx = app.controller('dashBoardController', ['$scope', function ($scope) {
$scope.value = 'Test';
}]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
<div ng-app="dashBoardApp">
<div ng-controller="dashBoardController">
<p>{{5+5}}</p>
</div>
</div>
i want execute a hello world function into a controller (call from html with button click), but i cant call this and i do not know why it does not work because not any show a error.
html code:
<html ng-app="app">
<div ng-controller="indexController">
<button type="button" ng-click="helloWorld()">action</button>
</div>
and controller js:
(function () {
'use stritct';
angular
.module('app',[])
.controller('indexController', indexController);
indexController.inject = ['$rootScope','$scope'];
function indexController($rootScope,$scope) {
var vm = this;
vm.helloWorld = helloWorld;
function helloWorld() {
console.log('hello');
}
}
})();
ng-click="helloWorld() will try to call $scope.helloWorld() function, that is undefined here.
helloWorld function is linked to your controller object, not to the Angular scope.
You have to set an alias of your controller, like ng-controller="indexController as index", and you will can call your helloWorld function like this: ng-click="index.helloWorld()".
To access functions or data in the template from your controller, you must define the function or value on the $scope object. Anything you define on the $scope object you can use in the template.
Instead of vm.helloWorld = helloWorld; try $scope.helloWorld = helloWorld;
In the same way, you can access data from your controller and display it in the template.
angular.module('app',[])
.controller('indexController', indexController);
indexController.$inject = ['$rootScope','$scope'];
function indexController($rootScope,$scope) {
$scope.helloWorld = function() {
console.log('hello');
}
$scope.message = 'From the controller!';
}
<html ng-app="app">
<body>
<div ng-controller="indexController">
<button type="button" ng-click="helloWorld()">action</button>
<p>{{ message }}</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</body>
</html>
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
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>
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++;
};
}])