Why doesn't step 3 of the AngularJS Tutorial work? - javascript

In step 3 of the AngularJS Tutorial AngularJS tutorial the the example suggests adding another e2e test:
it('should display the current filter value within an element with id "status"',
function() {
expect(element('#status').text()).toMatch(/Current filter: \s*$/);
input('query').enter('nexus');
expect(element('#status').text()).toMatch(/Current filter: nexus\s*$/);
//alternative version of the last assertion that tests just the value of the binding
using('#status').expect(binding('query')).toBe('nexus');
});
The test initially fails, adding the following to the page is supposed to make it pass. Having added it my page is like this:
<!doctype html>
<html lang="en" ng-app ng-controller="PhoneListCtrl">
<head>
<meta charset="utf-8">
<title ng-bind-template="Google Phone Gallery: {{query}}">Google Phone Gallery</title>
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="css/bootstrap.css">
<script src="lib/angular/angular.js"></script>
<script src="js/controllers.js"></script>
</head>
<body ng-controller="PhoneListCtrl">
<div class="container-fluid">
<div class="row-fluid">
<div class="span2">
<!--Sidebar content-->
Search:
<input ng-model="query">
<div id="status">
Current filter: {{query}}
</div>
</div>
<div class="span10">
<!--Body content-->
<ul class="phones">
<li ng-repeat="phone in phones | filter:query">
{{phone.name}}
<p>
{{phone.snippet}}
</p>
</li>
</ul>
</div>
</div>
</div>
</body>
The final assertation fails though: `
using('#status').expect(binding('query')).toBe('nexus');`
With the following message:
Chrome 23.0 PhoneCat App Phone list view should display the current filter value within an element with id "status" FAILED
expect select binding 'query' toBe "nexus"
I think this is because the element isn't actually bound to query, the contents of the element use that binding, however, what should I do the make it pass?
Thanks in advance
Dave
EDIT: Controllers.js
'use strict';
/* Controllers */
function PhoneListCtrl($scope) {
$scope.phones = [
{"name": "Nexus S",
"snippet": "Fast just got faster with Nexus S.",
"age": 0},
{"name": "Motorola XOOMâ„¢ with Wi-Fi",
"snippet": "The Next, Next Generation tablet.",
"age": 1},
{"name": "MOTOROLA XOOMâ„¢",
"snippet": "The Next, Next Generation tablet.",
"age": 2}
];
$scope.orderProp = 'age';
}

I see that you have used twice ng-controller="PhoneListCtrl". This is likely to cause problems. Remove the one on the html tag .

Related

AngularJS simple app webpage stops rendering code

I'm trying to go through an AngularJS tutorial on codeschool.com but as I work through it and refresh my browser to see my progress, at some point in the tutorial the browser always ends up loading a blank webpage and won't load the code anymore. I've attempted the tutorial from the start twice and it happened both times at different points.
I must keep doing something wrong in my code. Has anyone else had this issue or know how to fix it?
I've seen a couple similar questions on here but the answers haven't worked.
Here's the HTML:
<!DOCTYPE html>
<html ng-app='store'>
<head>
<html lang="en-US">
<link rel="stylesheet/css" type="text/css" href="bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
</head>
<body ng-controller="StoreController as store">
<div ng-repeat="product in store.products">
<h1> {{store.product.name}} </h1>
<h2> {{store.product.price}} </h2>
<p> {{store.product.description}} </p>
<button>Add to Cart</button>
</div>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
And here's the JS file:
(function (){
const app = angular.module('store', [ ]);
app.controller("StoreController", function(){
this.product = gems;
});
const gems = [
{
name: "Dodecahedron",
price: 2.95,
description: 'Many sided gem. Would look great in a ring.',
},
{
name: "Pentagonal Gem",
price: 5.95,
description: 'A gem shaped like a pentagon. More expensive and
more shiny',
}
];
})();
Two things: you have a mismatched variable name between your controller and your view and then inside your ng-repeat you are including your controller alias instead of accessing each of the repeated elements directly.
First change this.product = gems; in your controller to this.products = gems; and then change your ng-repeat div to this:
<div ng-repeat="product in store.products">
<h1> {{product.name}} </h1>
<h2> {{product.price}} </h2>
<p> {{product.description}} </p>
<button>Add to Cart</button>
</div>

Multiple controllers working within ngRoute example

I have a small ngRoute example I am trying that to use multiple applications and controllers with. The first app/controller is for the main page, while the second set of app/controller is for the html that ngRoute loads up after pressing a button. However, it doesn't seem to be working. Code below:
Main Module
var app = angular.module("MainModule", ["ngRoute"]);
Main Controller
app.controller("MainController", function ($scope) {
});
app.config(function ($routeProvider) {
$routeProvider
.when('/customers', {
templateUrl: "customers.html",
controller: "CustomerController"
})
});
Customer Module
var CustomerModule = angular.module("CustomerModule", []);
Customer Controller
CustomerModule.controller("CustomerController", function ($scope) {
$scope.Test = "Hey";
$scope.CustomerArray = [
{ "firstName" : "John", "lastName" : "Williams", "Occupation" : "Fireman" },
{ "firstName" : "Louis", "lastName" : "Abrams", "Occupation" : "Policeman" }
]
});
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<script src="scripts/MainModule.js"></script>
<script src="scripts/MainController.js"></script>
<link rel="stylesheet" type="text/css" href="MyCSS.css">
</head>
<body>
<div ng-app="MainModule">
<div id="TopDiv">Main Module</div>
<input type="button" value="Load Customers" />
<div ng-view></div>
</div>
</body>
</html>
customers.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="scripts/CustomerModule.js"></script>
<script src="scripts/CustomerController.js"></script>
</head>
<body>
<div ng-app="CustomerModule" ng-controller="CustomerController">
{{Test}}
<ul>
<li ng-repeat="x in CustomerArray">{{x.firstName x.lastName x.Occupation}}</li>
</ul>
</div>
</body>
</html>
Long bits of code there, but hopefully simple code. The output when I press the "Load Customer" button is literally {{Test}} with no array data to follow.
I am just now learning angular, so any help with this issue I would appreciate. I am just doing this for fun, to try to learn. So I suppose the issue is not pressing. :) Thanks!
I wrote out a working example using the code from the question as a base. There are quite a few adjustments that were made, so I will list each piece with a bit of explanation.
It is not necessary for each "page" to have it's own module. However, it is not a bad practice. To support the design you have here of one module for each view, I made the following changes:
Include the CustomerModule as a dependency in the MainModule (MainModule.js):
var app = angular.module("MainModule", ["ngRoute", "CustomerModule"]);
Load ALL scripts in the index.html:
<script src="scripts/MainModule.js"></script>
<script src="scripts/MainController.js"></script>
<script src="scripts/CustomerModule.js"></script>
<script src="scripts/CustomerController.js"></script>
With these changes, the $routeProvider is able to locate the CustomerController and instantiate it during a route change. The customers.html now does not have to create a controller, and can be stripped down to a complete partial. Also, the expression used in customers.html needed to be changed, and broken down into individual expressions for each property.
The final customers.html:
{{Test}}
<ul>
<li ng-repeat="x in CustomerArray">{{x.firstName}} {{x.lastName}} {{x.Occupation}}</li>
</ul>
Complete working sample on plnkr.co: http://plnkr.co/edit/EjwW9Fsc2DPhBejUETwB?p=preview
I'm not sure, but the problem is in your MainModule. It should be like this or so:
var app = angular.module("MainModule", ["ngRoute"]);
When you calling angular.module with only one parameter - it's only trying get module, not create.
And customers.html should only contains parts of you html, not full:
Full customers.html
{{Test}}
<ul>
<li ng-repeat="x in CustomerArray">{{ x.firstName }} {{ x.lastName }} {{ x.Occupation }}</li>
</ul>
And add move customer js files to index.html:
<script src="scripts/MainModule.js"></script>
<script src="scripts/MainController.js"></script>
<script src="scripts/CustomerModule.js"></script>
<script src="scripts/CustomerController.js"></script>
<link rel="stylesheet" type="text/css" href="MyCSS.css">
Hope, it helps.

ng-model isn't being selected from an ng-options

<select class="form-control"
id="projects"
ng-model="parent_id"
ng-options="project.id as project.groupingName for project in projects">
</select>
There is a project that has a gid that matches the parent_id, but it still doesn't come as selected by default. To prove it, I did:
<div ng-repeat="project in projects" ng-show="project.gid === parent_id">
{{ project }}
</div>
I see there's a gap in your code for parent_id and project id. I wrote some code for your requirement. If I understand correctly, you want to display the project if ID of that project equals parent_id. I've update ng-options for you correctly as they should track by "id" of the project.
Are you looking for something like http://codepen.io/aechannaveen/pen/NABbXq ?
<html ng-app="myApp">
<head>
<title>
My Angular App
</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js">
</script>
</link>
</head>
<body class="container" ng-controller="InputCtrl">
<select class="form-control" id="projects" ng-model="project" ng-options="project as project.groupingName for project in projects track by project.id">
</select>
<div ng-show="project.id === parent_id">
Project Selected :{{ project.groupingName }}
</div>
</body>
</html>
And
angular.module('myApp', []).controller('InputCtrl', ['$scope',function($scope) {
$scope.parent_id = 2;
$scope.projects = [
{
"groupingName": "ABC",
"id": 1
},
{
"groupingName": "CDE",
"id": 2
} ];
}]);

Angular ng-repeat unused warning

I'm learning angular js, I'm trying some examples and I'm getting unused warning from netbeans. When I run the file in browser it doesn't show anything but from the tutorial I'm watching it works, it doesn't work on my side. here is the code.
<html ng-app>
...
<div ng-controller="test">
<ul>
<li ng-repeat="cust in customers">{{ cust.name }}</li>
</ul>
</div>
<script src="js/angular.min.js" type="text/javascript"></script>
<script>
function test($scope){
$scope.customers = [
{name: 'Dave Jones', city: 'Phoenix'},
{name: 'Jamie Riley', city: 'Atlanta'},
{name: 'Heedy Wahlin', city: 'Chandler'},
{name: 'Thomas Winter', city: 'Seattle'}
];
}
</script>
example on jsfiddle
console errors.
Add no wrap in body in js fiddle
Like this
try to use angular in proper way
like this
view
<html ng-app="app">
<body>
<div ng-controller="myCtrl">
<!-- do something -->
</div>
<script src="your angular library file path"></script>
<script src="app.js path"></script>
</body>
app.js
var app=angular.module("app",[]);
app.controller("myCtrl",["$scope",function($scope){
// put your code
}]);
The same error also arise due to duplicate keys. There you can use track by $index
<ul>
<li ng-repeat="cust in customers track by $index">{{ cust}}</li>
</ul>

Angularjs external templating: the template cannot be loaded?

I thought loading an external template with Angularjs is as simple as this below,
<div ng-include='template/index.php'></div>
But it does not print anything out on the browser. What have I missed?
The html,
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Angualr</title>
<meta charset="utf-8">
<script src="js/angular.min.js"></script>
<script src="js/app.js" type="text/javascript"></script>
<script src="js/maincontroller.js" type="text/javascript"></script>
</head>
<body>
<div ng-include='template/index.php'></div>
</body>
</html>
the template,
<div id='content' ng-app='MyTutorialApp' ng-controller='MainController'>
<input type='text' ng-model='searchText' />
<ul>
<li ng-repeat='person in people | filter:searchText' ng-show='person.live == true'>#{{person.id}} {{person.name}}</li>
</ul>
<input type='text' ng-model='newPerson' />
<button ng-click='addNew()'>Add</button>
</div>
js/app.js,
var app = angular.module('MyTutorialApp',[]);
js/maincontroller.js,
app.controller("MainController", function($scope){
$scope.people = [
{
id: 0,
name: 'Leon',
music: [
'Rock',
'Metal',
'Dubstep',
'Electro'
],
live: true
},
{
id: 1,
name: 'Chris',
music: [
'Indie',
'Drumstep',
'Dubstep',
'Electro'
],
live: true
}
];
$scope.newPerson = null;
$scope.addNew = function() {
if ($scope.newPerson != null && $scope.newPerson != "") {
$scope.people.push({
id: $scope.people.length,
name: $scope.newPerson,
live: true,
music: [
'Pop',
'RnB',
'Hip Hop'
]
});
}
}
});
EDIT:
Directories,
index.html
js/
...
...
template/
index.php
EDIT 2:
index.html,
<div ng-app='MyTutorialApp'>
<div ng-include='template/index.php'></div>
</div>
template/index.php,
<div id='content' ng-controller='MainController'>
<input type='text' ng-model='searchText' />
<ul>
<li ng-repeat='person in people | filter:searchText' ng-show='person.live == true'>#{{person.id}} {{person.name}}</li>
</ul>
<input type='text' ng-model='newPerson' />
<button ng-click='addNew()'>Add</button>
</div>
Live demo here (click).
ng-include looks for a $scope property, so you need to pass it a string, like this: ng-include="'/template/index.php'".
<div ng-include="'/template/index.php'"></div>
What you were passing to it essentially makes it look for this in your controller: $scope['/template/index.php'] = 'some string';
You're also bootstrapping angular in the template itself - so how could it be included? ng-app needs to be in the main page so that ng-include can work!
<some-element ng-app="myApp">
<!-- in here, angular things work (assuming you have created an app called "myApp" -->
<div ng-include="'/template/index.php'"></div>
</some-element>
Just replace some-element with something like html, body or whatever element you want the app to work from.
You bootstrapped your ng-app in the template, but you have to bootstrap it in your main page.
So just move the ng-app directive from the template to the main-page, e.G.
<html ng-app="MyTutorialApp">
<div ng-include src='template/index.php'></div>
try this
and add ng-app into top of the page
<html ng-app='MyTutorialApp'>
you must have bootstrap you angular application into your index.html

Categories

Resources