I am reading an AngularJS book. I copied the following code from the book:
<!DOCTYPE html>
<html ng-app='myApp'>
<head>
<title>Your Shopping Cart</title>
</head>
<body ng-controller='CartController'>
<h1>Your Order</h1>
<div ng-repeat='item in items'>
<span>{{item.title}}</span>
<input ng-model='item.quantity'>
<span>{{item.price | currency}}</span>
<span>{{item.price * item.quantity | currency}}</span>
<button ng-click="remove($index)">Remove</button>
</div>
<script src="js/lib/angular.min.js"></script>
<script>
function CartController($scope) {
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}
</script>
</body>
</html>
I have the angular.min.js in place. However, I got this output from Chrome:
Apparently, there is something wrong with the code. However, as a newbie, I cannot tell where it is. Your help is greatly appreciated. Thank you very much.
update
Here is the error output:
Failed to instantiate module myApp due to:
Error: [$injector:nomod] http://errors.angularjs.org/1.2.10/$injector/nomod?p0=myApp
at Error (native)
at http://localhost:63342/angular-book/js/lib/angular.min.js:6:450
at http://localhost:63342/angular-book/js/lib/angular.min.js:20:260
at http://localhost:63342/angular-book/js/lib/angular.min.js:21:262
at http://localhost:63342/angular-book/js/lib/angular.min.js:29:175
at Array.forEach (native)
at q (http://localhost:63342/angular-book/js/lib/angular.min.js:7:280)
at e (http://localhost:63342/angular-book/js/lib/angular.min.js:29:115)
at $b (http://localhost:63342/angular-book/js/lib/angular.min.js:32:232)
at Zb.c (http://localhost:63342/angular-book/js/lib/angular.min.js:17:431
You must register the CartController with your app "myApp"
One way to do it:
angular.module('myApp').controller('CartController',['$scope', function ($scope) {
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}]);
The AngularJS book from O'Reilly has lots of errors in it. You will have to fix lots of the code samples.
At the top of your app, you reference the name of the app, but don't register it.
<html ng-app='myApp'>
If you give a value here, you have to define the module.
angular.module('myApp', []);
You can also can assign the module to a variable for easy reference when you create controllers, etc:
var myApp = angular.module('myApp', []);
myApp.controller('myController',
function myController($scope){
};
But for a simple angular app using just one page of code, the easiest solution for your code is to just not assign a value to the ng-app attribute:
<html ng-app>
My complete working code for this example was:
<!doctype html>
<html ng-app>
<head>
<meta charset="utf-8">
<title>Your Shopping Cart</title>
</head>
<body ng-controller='CartController'>
<h1>Your Order</h1>
<div ng-repeat='item in items'>
<span>{{item.title}}</span>
<input ng-model='item.quantity'>
<span>{{item.price | currency}}</span>
<span>{{item.price * item.quantity | currency}}</span>
<button ng-click="remove($index)">Remove</button>
</div>
<script src="js/angular.min.js"></script>
<script>
function CartController($scope) {
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}
</script>
</body>
</html>
As Luke mentioned, you must define myApp somewhere. Dependencies (controllers, directives, etc) should be injected there:
angular.module('myApp', [
// myApp dependencies (controllers, etc.) injected here...
'myApp.controllers'
]).
config(['$routeProvider', function($routeProvider) {
// your routes here...
}]);
Then you have your controller, which is what gets injected...
angular.module('myApp.controllers', []).
controller('MyCtrl', [function() {
}]);
If you haven't already, take a look at the Angular seed project. This is an outstanding resource for anyone ramping up with Angular.
Related
How do you clear an array with selected values so that values can return to the select?
I have a people array. The people array values are available in select. When I choose names, they are transferred to the multipleDemo array. And you can not reselect them from select because they disappear and are moved to the multipleDemo array. With the Delete button I have to delete all elements from the multipleDemo array (except the first element) into the people array. So that you can again choose a name from the select. Error in function $clearTag.
Expecting behavior:
Example:
Select: Wladimir
Appear tag Wladimir
Select Wladimir (You can't choose Wladimir because he is already chosen)
Click Delete. Cut elements(tags) with multipleDemo array and put them in array people
You can again select Wladimir
Here is my code: http://plnkr.co/edit/TPZjXkkSRrIc5ApzP07F?p=preview
index.html
<!DOCTYPE html>
<html lang="en" ng-app="demo">
<head>
<meta charset="utf-8">
<title>AngularJS ui-select</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-sanitize.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.css">
<!-- ui-select files -->
<script src="select.js"></script>
<link rel="stylesheet" href="select.css">
<script src="demo.js"></script>
<!-- Select2 theme -->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css">
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.8.5/css/selectize.default.css">
<style>
body {
padding: 15px;
}
.select2 > .select2-choice.ui-select-match {
/* Because of the inclusion of Bootstrap */
height: 29px;
}
.selectize-control > .selectize-dropdown {
top: 36px;
}
</style>
</head>
<body ng-controller="DemoCtrl">
<h3>Array of strings</h3>
<button ng-click='clearTag()'>Delete</button>
<ui-select tagging tagging-label="new tag" multiple ng-model="multipleDemo"
on-select="OnClickSelect($item)" on-remove="OnRemoveSelect($item)"
theme="select2" ng-disabled="disabled" style="width: 300px;">
<ui-select-match placeholder="Select name...">{{$item.name}}</ui-select-match>
<ui-select-choices repeat="item in people | filter:$select.search">
{{item.name}}
</ui-select-choices>
</ui-select>
<p>Selected: {{multipleDemo}}</p>
<hr>
</body>
</html>
demo.js
app.controller('DemoCtrl', function($scope, $http, $timeout) {
$scope.multipleDemo =[];
$scope.people = [
{ name: 'Adam', email: 'adam#email.com', age: 12, country: 'United States' },
{ name: 'Amalie', email: 'amalie#email.com', age: 12, country: 'Argentina' },
{ name: 'Estefanía', email: 'estefania#email.com', age: 21, country: 'Argentina' },
{ name: 'Adrian', email: 'adrian#email.com', age: 21, country: 'Ecuador' },
{ name: 'Wladimir', email: 'wladimir#email.com', age: 30, country: 'Ecuador' },
{ name: 'Samantha', email: 'samantha#email.com', age: 30, country: 'United States' },
{ name: 'Nicole', email: 'nicole#email.com', age: 43, country: 'Colombia' },
{ name: 'Natasha', email: 'natasha#email.com', age: 54, country: 'Ecuador' },
{ name: 'Michael', email: 'michael#email.com', age: 15, country: 'Colombia' },
{ name: 'Nicolás', email: 'nicolas#email.com', age: 43, country: 'Colombia' }
];
$scope.OnClickSelect=function(item)
{
$scope.multipleDemo.push(item.name);
}
$scope.OnRemoveSelect = function(item) {
var index = $scope.people.indexOf(item.name);
$scope.people.splice(index, 1);
}
$scope.clearTag = function() {
for(var i =0; i < $scope.multipleDemo.length; i++) {
$scope.multipleDemo.splice($scope.multipleDemo[i], 1000);
$scope.people.push($scope.multipleDemo[i]);
}
}
Angular-UI-Select Common Issues
ng-model not working with a simple variable on $scope
You cannot write:
WRONG
<ui-select ng-model="multipleDemo"> <!-- Wrong -->
[...]
</ui-select>
You need to write:
<ui-select ng-model="vm.multipleDemo"> <!-- Correct -->
[...]
</ui-select>
For more information, see
AngularUI-Select FAQ - Common Issues
Update
vm.multipleDemo doesn't work; I try $parent.multipleDemo - it works. I don't understand $parent. Why it works?
For vm.multipleDemo to work, the controller must initialize the vm object:
app.controller('DemoCtrl', function($scope, $http, $timeout) {
$scope.vm = { multipleDemo: [] };
New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the [data hiding] problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)
This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.
— What are the nuances of scope prototypal / prototypical inheritance in AngularJS?
Avoid using $parent to fix a data hiding problem. It is a brittle solution as there can be more than one level of scope heirarchy between the controller and the ui-select directive. I consider the use of $parent to be a code smell, a symptom of a deeper problem.
Update #2
When I can use $ctrl in view and this in controller?
If the controller is instantiated with "controller as" syntax:
<body ng-controller="DemoCtrl as $ctrl">
<ui-select ng-model="$ctrl.multipleDemo">
<!-- -->
</ui-select>
Then there is no need to use $scope:
app.controller('DemoCtrl', function($http) {
this.multipleDemo = [];
And it avoids the data hiding problem.
For more information, see
'this' vs $scope in AngularJS controllers
First of all I want to say I am following this fiddle for Advanced live-search with AngularJS, which is working great, but for my scenario I need to search for both catergories and category childs.
Example list:
$scope.names = [
{
name: "Kitchen",
tags: [
"Knife",
"Plate",
"Fork"
]
},
{
name: "Garage",
tags: [
"Car",
"Wrench",
]
}
Scenario Search:
Input Search:
knife
Result:
<li><b>Kitchen</b></li>
<li>Knife</li>
Scenario Search 2:
Input Search:
garage
Result:
<li><b>Garage</b></li>
I've tried to make some form of 'double' ng-repeat with something
like this: ng-repeat="name in names || name in names by separating categories from childs but then there will be problem with populating the list. I also don't know the correct operator for AND but I can imagine there is a lot better solution for this but I can't figure out how, Note that I am pretty new to AngularJS and JS.
To make filter works in both arrays, you have to create a custom filter.
See it working:
angular
.module('app', [])
.controller('MainCtrl', MainCtrl)
.filter('customFilter', customFilter);
MainCtrl.$inject = ['$scope'];
function MainCtrl($scope) {
$scope.names = [
{
name: "Kitchen",
tags: [
"Knife",
"Plate",
"Fork"
]
},
{
name: "Garage",
tags: [
"Car",
"Wrench",
]
}
];
}
function customFilter() {
return function(items, search) {
if (!search) return items;
search = search.toLowerCase();
return items.filter(function(item) {
return item.name.toLowerCase().indexOf(search) !== -1 || item.tags.filter(function(tag) {
return tag.toLowerCase().indexOf(search) !== -1;
}).length;
});
}
}
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<input type="text" placeholder="Search..." ng-model="search">
<ul ng-repeat="obj in names | customFilter: search track by $index">
<li><strong ng-bind="obj.name"></strong></li>
<ul>
<li ng-repeat="tag in obj.tags | filter: search track by $index" ng-bind="tag"></li>
</ul>
</ul>
</body>
</html>
I hope it helps.
I am new to angular.js just started learning, i want to Display the array defined in the Controller, But When I am trying to Display Its Showing empty page. I know if i change the ng-repeat=post in post1 to ng-repeat=post in posts" it ll work. But i want show the Error either in the Console or in the Browser. Please Can anybody help me.
var mainapp = angular.module('mainApp', []);
mainapp.controller('control', function ($scope) {
$scope.posts = [
{title: 'post 1', upvotes: 5},
{title: 'post 2', upvotes: 2},
{title: 'post 3', upvotes: 15},
{title: 'post 4', upvotes: 9},
{title: 'post 5', upvotes: 4}
];
});
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
</head>
<body ng-app="mainApp" ng-controller="control">
<div ng-repeat="post in post1 | orderBy:'upvotes'">
<p>{{post.title}}-upvotes {{post.upvotes}}</p>
</div>
</body>
</html>
This is not an error at all from angular point of vew. In fact it is quite usual to use variables in template which are undefined for now, but will get some value later.
I.e. imagine that you have in controller:
$timeout(function() {
$scope.post1 = [{title : 'test'}];
}, 100)
Use ng-if directive to check "post1" is undefined and display error message.
<div ng-repeat="post in post1 | orderBy:'upvotes'">
<p>{{post.title}}-upvotes {{post.upvotes}}</p>
</div>
<div ng-if="post1==undefined">
Error Message
</div>
I use Angular and Bootstrap to represent a data grid and give user some control over it (edit data, etc.). The data set is array of objects, each object has a group property, which is not unique and represents what group a record refers to.
So, the dataset looks like
[
{
id: 1,
group: 'A',
value: 'John'
}, {
id: 2,
group: 'A',
value: 'Jake'
}, {
id: 3,
group: 'B',
value: 'Jack'
}
]
I want Angular to output
<div class="row group">
<div class="col-md-12">A</div>
</div>
<div class="row sample">
<div class="col-md-4">1</div>
<div class="col-md-8">John
<div>
...
I tried ng-repeat but it only allows to fold arrays one into another, so the {{ group }} will be a top element and {{ elementOfAGroup }} will be its child. I need a final markup to be a plain set of DOM elements.
I googled for a solution but the only I've found were simple components (directives) that allow making up tables.
I have used custom "uniq" filter to accomplish this:
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.1.1/angular-filter.js"></script>
</head>
<body ng-app="plunker" ng-controller="MainCtrl">
<div class="row group" ng-repeat="data in dataset | uniq: 'group'">
<h3>{{data.group}}</h3>
<div class="col-md-12" ng-repeat="child in dataset | filter: { group: data.group }">{{child.value}}</div>
</div>
</body>
<script>
var app = angular.module('plunker', ['angular.filter']);
app.controller('MainCtrl', ['$scope', '$sce', function($scope, $sce) {
$scope.dataset = [
{
id: 1,
group: 'A',
value: 'John'
}, {
id: 2,
group: 'A',
value: 'Jake'
}, {
id: 3,
group: 'B',
value: 'Jack'
}
];
}]);
</script>
</html>
It may be slow with large data set.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 8 years ago.
Improve this question
I ma learning and its my first day to angular js ! though I have learned how model-controller-views works in angular js,the fowllowing code not showing the variables,instead it gives normal {{}} HTML views without ng-repeat working :
<html ng-app='myApp'>
<head>
<title>Your Shopping Cart</title>
</head>
<body ng-controller='CartController'>
<h1>Your Order</h1>
<div ng-repeat='item in items'>
<span>{{item.title}}</span>
<input ng-model='item.quantity'>
<span>{{item.price | currency}}</span>
<span>{{item.price * item.quantity | currency}}</span>
<button ng-click="remove($index)">Remove</button>
</div>
<script src="lib/angular.js"></script>
<script>
function CartController($scope) {
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}
</script>
</body>
</html>
Whats wrong with the code?
Just replace
<html ng-app='myApp'>
with
<html ng-app>
and it should work.
With ng-app='myApp' you tell angularjs that you have a module called myApp. But you define no module.
You should define your myApp module:
var app = angular.module('myApp', []);
app.controller('CartController', ['$scope', function($scope) {
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}]);
DEMO
Basically you didn't define module in controller.
<script>
angular.module('myApp', []); // add this line
function CartController($scope) {
$scope.items = [
{title: 'Paint pots', quantity: 8, price: 3.95},
{title: 'Polka dots', quantity: 17, price: 12.95},
{title: 'Pebbles', quantity: 5, price: 6.95}
];
$scope.remove = function(index) {
$scope.items.splice(index, 1);
}
}
</script>
Your Demo in Plunker