I am new to angular js. I was gone through the angular api references,
I had seen function called angular.bind(self, fn, args).
I could not understand the usage of this function. Can anyone explain this function with one example?
It used in Function Currying. An example with JavaScript:
var concat = function(input1) {
return function(input2) {
console.log(input1 + ", " + input2);
};
};
var externalFunction = concat("Hello");
externalFunction("World!"); // gives: "Hello, World!"
This allows you to use only some parameters and not all, for example concant("Hello") instead of concant("Hello","World!"). You can imagine using a defined variable as one of the parameters, whereas you fill in the second one from a user input. The same concept can be used with AnuglarJS:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
</head>
<body ng-app="app">
<div ng-controller="bindController">
<input type="number" ng-model="num" ng-change="AddValue()" />
Adding 5: {{Add}}
</div>
</body>
</html>
<script>
var app = angular.module("app", []);
app.controller('bindController',['$scope',function($scope){
$scope.num = 30;
$scope.AddValue = function () {
var addData = angular.bind(this, function (a, b) {return a + b;});
$scope.Add = addData(5, $scope.num);
}
$scope.AddValue();
}]);
</script>
Controller
app.controller('Identity`enter code here`Controller', ['$scope',
function($scope) {
$scope.Name = "";
$scope.Result = "";
var greet = function (greeting, punctuation) {
$scope.Result = greeting + ' ' + $scope.Name +''+ punctuation;
};
$scope.callBind = function () {
var bound = angular.bind(this, greet, 'Welcome');
bound('!!!!!');
};
}]);
html
<fieldset style="background-color:#DDE4E9;">
<legend>AngulerJS $scope.bind() Example</legend>
<div ng-controller="IdentityController">
<p>{{Result}}</p>
<input ng-model="Name">
<button ng-click="callBind()">Call Bind</button>
</div>
</fieldset>
I Think Its Working
Related
I have an AngularJS script (to be run on the web) and a couple of specific functions are starting to become very long, long enough that I've built a spreadsheet to generate all of the different cases, which I then simply paste into the code.
(function(){
var app = angular
.module('app',[])
.controller('HostController',HostController);
HostController.$inject = ['$scope'];
function HostController($scope){
var host = this;
host.variable = "some text";
function reallyLongFunction(a,b) {
switch(a) {
case "something":
switch(b) {};
break;
case "something else":
switch(b) {};
break;
};
}
}
})();
I want to move them out of the main file so that it's not cluttered with these long, generated functions while I work on the rest of the programme.
I could simply move the functions directly into another file, but they need to access variables of the type host.variable, and so need to be in the scope of the main Angular app, I believe?
How can I move these functions into a different file while retaining their access to these variables?
You can move your method to separate file by creating an angular service as well. Inject that service in your controller and access the method like someSvcHelper.reallyLongFunction(a,b). This aproach will also make this method of yours as generic and will be available for other controllers as well.
But in this case you will have to pass the variables required by this function as arguments.
Using nested ng-controller's you can have access to the other controller scope in the $scope.
angular.module('app', [])
.controller('ctrl', function() {
var vm = this;
vm.value = 1;
})
.controller('auxCtrl', function($scope) {
var aux = this;
aux.result = function() {
return $scope.vm.value + 5;
}
});
<div ng-app="app" ng-controller="ctrl as vm">
<div ng-controller="auxCtrl as aux">
<input type="number" ng-model="vm.value" /> <br/>
{{vm.value}} <br/>
{{aux.result()}}
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
Edit: What if i need more than one controller?
Well, in this case i think that nested controllers will be really cumbersome, so you can try a service that has an instance of the controllers scope.
angular.module('app', [])
.service('greeter', function() {
const self = this;
self.scope = {};
self.use = scope => self.scope = scope;
self.greet = () => 'Hello, ' + self.scope.myName;
})
.service('fareweller', function() {
const self = this;
self.scope = {};
self.use = scope => self.scope = scope;
self.farewell = () => 'Goodbye, ' + self.scope.myName;
})
.controller('ctrl', function($scope, greeter, fareweller) {
$scope.myName = 'Lorem Ipsum';
$scope.greeter = greeter;
$scope.fareweller = fareweller;
greeter.use($scope);
fareweller.use($scope);
});
<div ng-app="app" ng-controller="ctrl">
<input type="text" ng-model="myName"> <br>
{{greeter.greet()}} <br>
{{fareweller.farewell()}} <br>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
Getting started with AngularJS working through the W3schools tutorial.
I'm trying to expand on some of the sample code by creating an input which is used by the function getHex(), which uses the service hexafy.
<div ng-app="myApp" ng-controller="myCtrl">
<p>The hexadecimal value of <input ng-model="inputNo"/> is:</p>
<h1>{{getHex()}}</h1>
</div>
<p>A custom service with a method that converts a given number into a hexadecimal number.</p>
<script>
var app = angular.module('myApp', []);
app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
app.controller('myCtrl', function($scope, hexafy) {
$scope.inputNo = 255;
$scope.getHex = function() {
return hexafy.myFunc($scope.inputNo);
};
});
</script>
When the page firsts load, the input contains 255 and the {{getHex()}} is rendered as ff, so the function appears to run correctly.
But when I change the value in the input, it just returns exactly my input into {{getHex()}} without hexify-ing it. getHex() is supposed to return the result of hexafy.myFunc.
convert the $scope.inputNo to int before sending to the service
return hexafy.myFunc(parseInt($scope.inputNo));
Demo
Convert the sent payload to a javascript Number before converting to hex.
var app = angular.module('myApp', []);
app.service('hexafy', function() {
var hexafyService = {};
var _myFunc = function(x) {
return Number(x).toString(16);
}
hexafyService.myFunc = _myFunc;
return hexafyService;
});
app.controller('myCtrl', function($scope, hexafy) {
$scope.inputNo = 200;
$scope.getHex = function() {
$scope.hexNo = hexafy.myFunc($scope.inputNo);
};
$scope.getHex();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<p>The hexadecimal value of <input ng-model="inputNo" ng-change="getHex()" /> is:</p>
<h1>{{hexNo}}</h1>
</div>
<p>A custom service with a method that converts a given number into a hexadecimal number.</p>
i'm new to angularJs and want to learn more about it, i'm trying to display some users from a fake REST Api, when trying to run my code i got empty page and the console doesn't give me any errors , i don't know where is the error or where i can debug.
app.js
var myApp = angular.module("app", []);
contactsData.service.js look like that :
(function () {
var app = angular.module("app");
app.service("contactDataSvc", function ($http) {
var self = this;
self.getContacts = function () {
var promise1 = $http.get("http://localhost:3000/contacts");
var promise2 = promise1.then(function (response) {
return response.data;
});
return promise2;
}
});
})();
contacts.controller.js
(function () {
var myApp = angular.module("app");
myApp.controller("contactsCtrl", contactsCtrl);
function contactsCtrl(contactDataSvc) {
contactDataSvc.getContacts()
.then(function(data){
this.contacts = data;
});
}
})();
finally my view index.html
<html ng-app="app">
<head>
<title></title>
<script src="angular.js"></script>
<script src="app.js"></script>
<script src="contacts.controller.js"></script>
<script src="contactsData.service.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" />
<!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>-->
</head>
<body class="container">
<div>
<div ng-controller="contactsCtrl as ctrl">
<div class="raw">
<ul class="list-group">
<li class="li-group-item" ng-repeat="obj in ctrl.contacts">
{{obj.name.title + " " + obj.name.first + " " + obj.name.last}}
</li>
</ul>
</div>
</div>
</div>
</body>
</html>
Small correction required in your contactsCtrl
function contactsCtrl(contactDataSvc) {
var vm = this;
contactDataSvc.getContacts()
.then(function(data){
vm.contacts = data;
});
}
You cannot use this inside the then callback as the scope will be different.
Corrected working example here : http://plnkr.co/edit/LLKJipkBbiZ17QjQpw1X
Refer more:
https://www.w3schools.com/js/js_scope.asp
What is the scope of variables in JavaScript?
1 - Is this url correct? http://localhost:3000/contacts
2 - Open the url on any browser, does it return any response ? JSON?
Please check this first to see if the problem is not on the server side.
Firstly inject $scope in controller because anything/data that we want to access over Html from controller needs to be binded on $scope.
So you controller would look like:
(function () {
var myApp = angular.module("app");
myApp.controller("contactsCtrl", contactsCtrl);
function contactsCtrl($scope,contactDataSvc) {
contactDataSvc.getContacts()
.then(function(data){
$scope.contacts = data;
});
}
})();
Secondly from the service you need to return a promise from it only then you will be able to get the data once the response is back from the API.
So,the updated service code is :
(function () {
var app = angular.module("app");
app.service("contactDataSvc", function ($http,$q) {
var self = this;
var defered = $q.defer();
self.getContacts = function () {
var promise1 = $http.get("http://localhost:3000/contacts");
promise1.then(function (response) {
defered.resolve(response.data);
});
return defered.promise;
}
});
})();
How to wrap this controller logic inside a angular function and use it in select html element. Here inside controller code is use as inline logic without function.
Controller:
var year = new Date().getFullYear();
var range = [];
range.push(year);
for(var i=1;i<20;i++) {
range.push(year + i);
}
$scope.years = range;
View:
<select ng-options="year for year in years">
</select>
You can declare a function like that :
$scope.myfunction = function(){
var year = new Date().getFullYear();
var range = [];
range.push(year);
for(var i=1;i<20;i++) {
range.push(year + i);
}
return range;
}
and in your HTML :
<select ng-model="selectedYear" ng-options="year for year in myfunction()"></select>
I think all you are missing is the ng-model from the select statement. Here is a working example:
(function() {
angular
.module("app", []);
angular
.module("app")
.controller("AppController", AppController);
AppController.$inject = ["$scope"];
function AppController($scope) {
var vm = this;
vm.selectedYear = "";
vm.years = [];
loadData();
function loadData() {
var year = new Date().getFullYear();
var range = [];
range.push(year);
for (var i = 1; i < 20; i++) {
range.push(year + i);
}
vm.years = range;
}
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.6.1" data-semver="1.6.1" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="AppController as vm">
<div>
<select ng-model="vm.selectedYear"ng-options="year for year in vm.years">
</select>
</div>
</body>
</html>
I'm new to AngularJS and have been learning it from W3Schools. My issue is that ng-click is not working properly. It's calling repeatedly. If I click on the element with ng-click once it calls the function once. If I click it again it calls the function twice. If I continue clicking the button the function is called as many times as I've clicked the element before.
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<h1 id="h12" ng-click="changeName()" style="cursor:pointer;">{{firstname}}</h1>
</div>
<script>
var count = 0;
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstname = "John";
$scope.changeName = function() {
var h12 = document.getElementById("h12").innerHTML;
alert(count);
if (count == 0) {
$scope.firstname = "Nelly";
changeNGClick(h12);
count++;
} else {
count++;
var x = "";
var div1 = document.getElementById("h12");
var align = div1.getAttribute("data-v");
alert(align);
$scope.firstname = align;
changeNGClick(h12);
}
}
return false;
});
function compile(element) {
var el = angular.element(element);
$scope = el.scope();
$injector = el.injector();
$injector.invoke(function($compile) {
$compile(el)($scope)
})
}
function changeNGClick(v) {
var el = document.getElementById("h12");
el.setAttribute("data-v", v);
compile(el);
}
</script>
<p>Click on the header to run the "changeName" function.</p>
<p>This example demonstrates how to use the controller to change model data.</p>
</body>
</html>
This is how the code will work. When I click the header which has the text John then it will change to display Nelly. If you click it again it should change back to John. The value will be saved on the <h1> tags data-v. I would also appreciate another way of doing this if you have any suggestions.