Simple AngularJS controller does not work - javascript

I've searched and read all possible explanations, but none have helped so far.
The problem is that the data binding with the curly brackets doesn't work (it only works if I define the module and controller in the index.html).
index.html :
<html lang="en" data-ng-app="myApp">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="css/main.css" media="screen">
<script src="controllers/listcontroller.js"></script>
<script src="js/app.js"></script>
<script data-require="angular.js#*" data-semver="2.0.0" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
</head>
<div class="main">
<body data-ng-controller="ListController">
<ul>
<li data-ng-repeat="test in tests">
<span>{{ test.name }}</span>
<p>{{ test.type }}</p>
</li>
</ul>
There are currently {{test.length}} tests available.
You have currently selected 0 tests.
<button class="animatedbutton"> Proceed </button>
</div>
</body>
</html>
app.js (in folder js):
(function () {
'use strict';
angular.module('myApp', ['myApp.controller']);
})();
listcontroller.js (in folder controllers):
(function () {
'use strict';
var app = angular.module('myApp.controller');
app.controller('ListController', ['$scope', function ($scope) {
$scope.tests = [
{'name': 'A',
'type': '1'},
{'name': 'B',
'type': '2'},];
}]);
})();
The view shows me something like this:
{{ test.name }}
{{ test.type }}
There are currently {{test.length}} tests available.
You have currently selected 0 tests.
I've followed a couple of tutorials, such as the Angular in 60 Minutes, AngularJS.org, and some on YT, but I always encounter the same problem. Any ideas?

there are several issues look at the plunker:
https://plnkr.co/edit/bnYAsGk273kO5znMnAJh
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.js"></script>
<script src="listcontroller.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="ListController">
<div class="main">
<ul>
<li ng-repeat="test in tests">
<span>{{ test.name }}</span>
<p>{{ test.type }}</p>
</li>
</ul>
There are currently {{test.length}} tests available. You have currently selected 0 tests.
<button class="animatedbutton"> Proceed </button>
</div>
</body>
</html>
app.js
(function() {
'use strict';
angular.module('myApp', ['myApp.controller']);
})();
listcontroller.js
(function() {
var ctr = angular.module('myApp.controller', []);
ctr.controller('ListController', ['$scope',
function($scope) {
$scope.tests = [{'name': 'A','type': '1'}, {'name': 'B','type': '2' }];
}
]);
})();

You created a second module so you need to have the [] again:
var app = angular.module('myApp.controller', []);
Can you also include the console to see if there are any errors?

Related

Getting an error in AngularJS

I am creating a small web app where I will show a chart of the top 10 popular TV shows. Then, When I go to the browser and inspect I get an error:
Error: [$injector:unpr] http://errors.angularjs.org/1.5.6/$injector/unpr?p0=showProvider%20%3C-%20show%20%3C-%20MainController
<!doctype html>
<html>
<head>
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="css/main.css" rel="stylesheet" />
<!-- Angular JS -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<body ng-app="Top10App">
<div class="header">
<div class="container">
10
</div>
</div>
<div class="main" ng-controller="MainController">
<div class="container">
<div class="content">
<!--TODO: Loop through shows and display each one with this HTML-->
<!--ng-repeat="show in shows" -->
<div>
<div class="rank">{{$index + 1}}</div>
<h2 class="series"> {{ index.series }}</h2>
<p class="genre">{{ index.genre }} </p>
<p class="run-start"> {{ index.run_start }}</p>
<p class="description"> {{ index.description }} </p>
</div>
</div>
</div>
</div>
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/MainController.js"></script>
<!-- Services -->
<script src="js/services/show.js"></script>
</body>
</html>
Javascript
MainController.js
app.controller('MainController', ['$scope', 'show', function ($scope, show) {
show.success(function(data) {
$scope.show = data;
});
}]);
show.js
app.factory('Top10App', ['$http', function($http){
return $http.get('shows.json')
.success(function(data){
return data;
})
.error(function(err){
return err;
});
}]);
You're defining your service name as 'Top10App', so that's the way you should access it, not by the file name.
['$scope', 'Top10App', function ($scope, Top10App) { ...
Top10App.success(...
First, do you created the module? You should has something like:
// app.js
angular.module('app', []);
// maincontroller.js
angular.module('app').controller('myController, ...', [.......]);
// factory.js
angular.module('app').factory(...)
You are trying to inject show as a dependency for your controller, but it doesn't look like that is defined anywhere. That's why your error is telling you that it's an unknown provider.
I'm guessing you're trying to use your Top10App factory, so you need to inject it as such
app.controller('MainController', ['$scope', 'Top10App', function ($scope, Top10App) {
Top10App.success(...)
}

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.

AngularJS uibModal dependency not found

I am having a problem with injecting the uibModal dependency in my app.js:
Angular Version: 1.5.7
ui.boostrap Version: 1.3.3
Bootstrap Version: 3.3.6
I keep getting this error:
angular.js:13708 Error: [$injector:unpr] Unknown provider: $uibModal Provider <- $uibModal <- ModalController
App.js:
var app = angular.module('App', ['ui.bootstrap', 'ui.bootstrap.tpls']);
app.controller('ModalController', ['$scope', '$uibModal ', function($scope, $uibModal) {
$scope.showModal = function() {
var modalInstance = $uibModal.open({
animation: true,
templateUrl: '../HTML/templates/login-modal.html',
controller: 'newModalController',
show: true
});
};
}]);
app.controller('newModalController', function($scope, $uibModalInstance) {
$scope.close = function() {
$uibModalInstance.dismiss('close');
};
});
Index.html:
<html lang="en">
<head>
<title>App</title>
<link rel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://cdn.jsdelivr.net/angular.bootstrap/1.3.3/ui-bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/angular.bootstrap/1.3.3/ui-bootstrap-tpls.min.js"></script>
<script src="../resources/js/app.js"></script>
</head>
<body ng-app="App">
<header>
<nav>
<div class="row" ng-controller="ModalController">
<img src="../resources/img/logos.png" alt="logo" class="logo">
<ul class="nav-list">
<li>Learn More</li>
<li>Take Action</li>
</ul>
</div>
</nav>
</header>
</body>
</html>
You also need ui-bootstrap-tpls for modal.
To anyone who needs help with this using the versions:
Angular Version: 1.5.7
Angular Animate: 1.5.7
ui.boostrap-tpls Version: 1.3.3
Bootstrap Version: 3.3.6
In your main index.html include the scripts. You only need angular, angular-animate, ui.boot-tpls, and bootstrap:
<html lang="en">
<head>
<title>App</title>
<link rel="stylesheet"href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="../vendors/js/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular-animate.js"></script>
<script src="../vendors/js/ui-bootstrap-tpls-1.3.3.min.js"></script>
<script src="../resources/js/app.js"></script>
</head>
<body>
...
</body>
</html>
first of all you have two controllers doing the same thing .when you can simply have one but in this case it's not the problem just a bad design.
try rewriting your first controller so instead of this
app.controller('ModalController', ['$scope', '$uibModal ', function($scope, $uibModal) {
do this :
app.controller('ModalController', function ($scope, $uibModal) {
dont forget to remove the ']' at the end of the controller
hope this helps !

console.log for $scope in angular js

Why I'm not able to console output $scope values ? I'm trying to extract user assigned values from the pages and retrieve in controller. Eventually i would like to pass this to service so multiple controllers can access these data.
HTML
<!DOCTYPE html>
<html lang="en-us" ng-app="myApp">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta charset="UTF-8">
<link rel="stylesheet" href="css/bootstrap.min.css" />
<!-- CDN lib files -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.0/ui-bootstrap-tpls.min.js"></script>
<!-- custom angular script -->
<script src="js/app.js"></script>
</head>
<body>
<div class="container">
<div ng-controller="mainController">
<h1>Hello world!</h1>
<label> Please enter something</label>
<input textarea ng-model="name"></input>
<h4> This is what you entered : {{ name }} </h4>
<h4 style=color:red> now filtering: {{ lower() }}</h4>
</div>
</div>
</body>
</html>
APP.JS
var myApp = angular.module('myApp', []);
myApp.controller('mainController', ['$scope', '$filter', function($scope, $filter) {
$scope.name = 'Test ';
$scope.lower = function(){
return $filter('lowercase')($scope.name);
}
$scope.name = $scope.lower();
console.log($scope.name);
console.log($scope.lower());
}]);
Console will output values upon initializing but not after user make changes.
You need to watch the scope variable:
$scope.$watch('name', function() {
console.log($scope.name);
});
More information: https://stackoverflow.com/a/15113029/5787736
Just a more "functional" version. Everyone is right, you are logging the observable, not what was observed. What you want is for console.log to be called on each change to $scope, not called once (as you have it now).
$scope.$watch("name", console.log);
You're logging only from the constructor. If you want to log each time something changes, consider a watch:
$scope.$watch("name", function() {
console.log($scope.name);
}
Why would you expect a controller to be rerendered when a scope variable changes? You can use scope watchers or input event listeners to listen for changes.
Here's an example with a watcher:
var myApp = angular.module('myApp', []);
myApp.controller('mainController', ['$scope', '$filter', function($scope, $filter) {
$scope.name = 'Test ';
$scope.lower = function(){
return $filter('lowercase')($scope.name);
}
$scope.name = $scope.lower();
console.log($scope.name);
console.log($scope.lower());
$scope.$watch('name', function() {
console.log($scope.name);
console.log($scope.lower());
});
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" class="container">
<div ng-controller="mainController">
<h1>Hello world!</h1>
<label>Please enter something</label>
<input textarea ng-model="name" />
<h4> This is what you entered : {{ name }} </h4>
<h4 style=color:red> now filtering: {{ lower() }}</h4>
</div>
</div>

angular-route is not working it does not throw any errors

I have a very simple app. When I start the app it works fine, both angular and angular-route are loaded, the config function is executed and "otherwise" works as intended.
However, both boxes and versions do not work and no HTML is injected. The main page just says
<!-- ngView: -->
and that's it.
THERE ARE 0 ERROR MESSAGES!!! The console is just empty as a desert.
I tried everything and it should work but it doesn't. I even tried replacing the browserify calls and including angular directly in the html - no success.
HTML:
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<title>app</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<header class="mainheader">
<div class="client-logo"></div>
<div class="logo"></div>
</header>
<nav class="mainmenu">
<ul>
<li class="active">Boxes</li>
<li>Versions</li>
</ul>
</nav>
<div ng-view></div>
<footer></footer>
</body>
<script src="./js/bundle.js"></script>
</html>
My JS:
'use strict';
require('angular/angular');
require('angular-route/angular-route');
var controllers = require('./controllers');
var app = angular.module('app', ['ngRoute']);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider
.when('/boxes', {
tamplate: 'views/boxes.html',
controller: 'boxController'
})
.when('/versions', {
tamplate: 'views/versions.html',
controller: 'versionsController'
})
.otherwise({
redirectTo: '/boxes'
});
}
]);
app.controller('boxController', controllers.boxController);
app.controller('versionsController', controllers.versionsController);
Example view:
<h2>Boxes</h2>
<p>{{ message }}</p>
Example controler:
'use strict';
exports.boxController = function($scope) {
$scope.message = 'Box Controller';
console.log('boxes');
};
exports.versionsController = function($scope) {
$scope.message = 'Versions Controller';
console.log('versions');
};
I'm as stupid as they come, the problem is a spelling error, it's tEmplate!
Thanks for the responses.

Categories

Resources