AngularJS can't find my controller - angularjs

I know this is a common problem but I haven't been able to find a solution by reading through previously asked questions.
I'm actually getting two errors but the first one is about angular not being able to find my controller.
http://errors.angularjs.org/1.4.2/$injector/nomod?p0=myApp.controllers
My directory structure looks like the following:
.
└── static
├── index.html
├── js
│   ├── app.js
│   └── controllers.js
├── lib
│   └── angular-ui-router.min.js
└── partials
├── view1.html
└── view2.html
My index file looks like the following:
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Hello AngularJS</title>
</head>
<body>
<div ui-view></div>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular.min.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.2/angular-route.min.js"></script>
<script type="text/javascript" src="lib/angular-ui-router.min.js"></script>
<script type="text/javascript" src="js/controllers.js"></script>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
My app.js file looks like the following:
(function(angular) {
var app = angular.module('myApp', ['ui.router', 'myApp.controllers']);
app.config(function($stateProvider) {
$stateProvider.state('view1', {
url: '/view1',
templateUrl: 'partials/view1.html',
controller: 'View1Controller'
}).state('view2', {
url: '/view2',
templateUrl: 'partials/view2.html',
controller: 'View2Controller'
});
}).run(function($state) {
$state.go('view2');
});
})(angular);
My controller.js file looks like the following:
(function(angular) {
var app = angular.module('myApp.controllers');
app.controller('View1Controller', function($scope) {
$scope.data = 'my view 1';
});
app.controller('View2Controller', function($scope) {
$scope.data = 'my view 2';
});
})(angular);
Also a second error which might be related.
As stated above angular is unable to find my controller. Does anyone have a clue about what I'm doing wrong? Please let me know if I need to paste more code.
I've shared the code on github in case someone finds it easier to deal with.
https://github.com/tonsV2/angular-ui.route/tree/master/src/main/resources/static

In angular angular.module() is a setter and a getter. According to the angular.module docs (via #DanAtkinson's comment):
Passing one argument retrieves an existing angular.Module, whereas
passing more than one argument creates a new angular.Module.
Getter
var app = angular.module('myApp.controllers'); uses module as a getter.
It fails because the module myApp.controllers haven't been created yet.
Setter
To use it as a setter change it to
var app = angular.module('myApp.controllers', []); // note the []

Related

Angular js controller not working after modularizing app

I'm new to angularjs and followed the tutorial here from w3schools to create my first simple Angularjs app and it worked fine. After going through the official angularjs tutorial I decided to modularize my app but now its not working. Currently I m getting the error
"The controller with the name 'redController' is not registered."
I want to display a message in component 'red' using its controller. I tried altering many parts of the code only to get new errors and it seems I have messed up modularizing :|
I'm using v1.6.9
Here is my directory structure
app/
scripts/
angular.min.js
angular-route.js
blue/
blue.template.html
red/
red.template.html
red.module.js
red.component.js
app.config.js
app.module.js
index.html
and source files :
app.config.js
angular
.module("myApp", [ 'red','ngRoute' ])
.config(function($routeProvider) {
$routeProvider
.when("/red", {
templateUrl : "red/red.template.html",
controller: "redController"
})
.when("/blue", {
templateUrl : "blue/blue.template.html"
});
});
app.module.js
angular.module('myApp', [
'red',
'ngRoute'
]);
index.html
<!DOCTYPE html>
<html>
<script src="scripts/angular.min.js"></script>
<script src="scripts/angular-route.js"></script>
<script src="app.module.js"></script>
<script src="app.config.js"></script>
<script src="red/red.module.js"></script>
<script src="red/red.component.js"></script>
<body ng-app="myApp">
Red
Blue
<div ng-view></div>
<p>Click on the links to navigate "</p>
</body>
</html>
red.template.html
<h1>red</h1>
<p>{{msg}}</p>hell
red.module.js
angular.module('red', [ 'ngRoute' ]);
red.component.js
angular.module('red').component('red',{
templateUrl: 'red/red.template.html',
controller: function redController() {
this.msg = "this is red";
console.log("Hi");
}
});
You are delcaring the module again and again in each .js files, declare only in one .js file and use it in rest of the fields.
change your red.module.js as,
angular.module('red', []);
your app.config.js should be as,
angular
.module("myApp")
.config(function($routeProvider) {
$routeProvider
.when("/red", {
templateUrl : "red/red.template.html",
controller: "redController"
})
.when("/blue", {
templateUrl : "blue/blue.template.html"
});
});
and change the order as follows,
<script src="red/red.module.js"></script>
<script src="app.module.js"></script>
<script src="app.config.js"></script>
<script src="red/red.component.js"></script>
Change red.component.js as follows
angular.module('red')
.component('red',{
templateUrl:
'red/red.template.html',
})
.controller("redController",function($scope)
{
$scope.msg ="This is red";
});
First of all, as #Sajeetharan you're defining the myApp module twice. Inside your app.config.js and also in app.module.js. If you use angular.module with 2 parameters angular.module('app', []) you're setting the module, if you use angular.module('app') it'll work as a getter. So, in your app.config.js you should use the getter to configure your app.
Once you did that, you can configure your route to something like this:
angular.module('myApp').config(function($routeProvider){
$routeProvider.when('/red', { template: '<red></red>'});
})
I would use this approach since you defined the component in another module.
If you still want to use the approach you've implemented to set both the templateUrl and controller in the $routeProvider, you'll have to change your red component declaration to something like this:
angular.module('red')
.component('red', { templateUrl: 'red/red.template.html'})
.controller('redController', function(){
this.msg = 'This is red.';
});
I'vent tested this second approach as for me the first makes more sense.

using angular-ui-router with express/node, file structure

I am following this tutorial, and I have an app structure like this. I've tried to show only the relevant bits as it is sort of a lot of code.
/app
/views
index.ejs
/config
express.js
/public
/external_libs
angular.js
angular-ui-router.js
/js
app.js
controllers.js
/partials
home.html
server.js
Inside my express.js (relevant bit)
app.use(express.static('./public');
I am able to set up my angular controllers, so I know this directory is being hit. For example, my index.ejs
<html ng-app="myapp">
<head>
<script src="external_libs/angular.js"></script>
<script src="external_libs/angular-ui-router.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"</script>
</head>
<body ng-controller= "MainCtrl"> <!-- an alert in my controller fires, so I know the public directory is accessible, at least the js folder-->
<div ui-view></div>
</body>
</html>
In my app.js
var app = angular.module('myapp', ['ui.router']);
app.config([
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'partials/home.html'
});
}
]);
In controllers.js
var app = angular.module('myapp', []);
app.controller('MainCtrl', [
'$scope', function($scope) {
alert("This alert is indeed alerted");
}
]);
home.html
<h1> This is a test to see if the view on index.ejs is being populated </h1>
I have tried many different combinations for the "templateUrl" inside app.js, including
"partials/home.html"
"/partials/home.html"
"../partials/home.html"
None of these result in home.html being placed inside the div ui-view element on my index.ejs page. I realize I have posted a somewhat limited amount of code, but the fact that I am able to hit my controllers and see an alert message leads me to believe that I am almost there. I am using server side routing to render the initial index.ejs, but other than that I want to handle things client side. Does anyone know how to make angular-ui-router locate my partial with this set up?
The problem is with your controller declaration. Rather than referencing the module you recreate it (and override the existing module) by including the square brackets.
If you rewrite your controller as below it should work:
var app = angular.module('myapp');
app.controller('MainCtrl', [
'$scope',
function($scope) {
alert("This alert is indeed alerted");
}
]);
For more info, check out "Creation versus Retrieval" at https://docs.angularjs.org/guide/module

Can't attach angularjs service to controller

I'm getting this error when I try to attach a service to a controller:
[$injector:unpr] ... webSocketServiceProvider <- webSocketService <- videoMenuCtrl
I have a plunker defined with a fairly minimal setup that reproduces the problem:
http://plnkr.co/edit/ptaIaOhzOIG1mSi4bPyF?p=preview
Here are the main culprit files:
index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>title</title>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body ng-app="videoApp">
<section class="menu" ng-controller="videoMenuCtrl">
</section>
<script src="webSocketService.js"></script>
<script src="videoMenu.js"></script>
<script src="ngDialog.min.js"></script>
<script src="ngPopup.min.js"></script>
</body>
</html>
webSocketService.js:
(function(angular) {
'use strict';
angular.module('videoApp')
.factory('webSocketService', function($q) {
return{};
});
});
videoMenu.js:
'use strict';
var app = angular.module('videoApp', ['ngDialog', 'ngPopup']);
app.controller('videoMenuCtrl', function($scope, $window, $location, ngDialog, webSocketService) {
});
I don't get an error if I remove the webSocketService from the controller, but the point is to have the controller be able to access the webSocketService. Any ideas? Thanks!
Edit: Changed file name typo.
I got your code working. Two things I noticed:
In you webSocketService.js you were re-declaring the videoApp module.
You were declaring the module inside a function expression that was not being invoked.
I re-declared your service in a properly namespaced module and wrapped it in an immediately invoked function expression.
I also removed your var app = declaration from your videoMenuCtrl and wrapped it in an IIFE as well. This is to avoid cluttering the global namespace. Here is a working plunk:
http://plnkr.co/edit/A8BcATiaqhXCA7BZDXWx?p=preview
EDIT (clarification) The IIFEs are not strictly necessary in my example plunk because the var app = declaration was removed from the code. That was the only variable that was being declared on the global namespace in the original example. However, wrapping the code in IIFEs has no negative effects as far as I know.

Error injecting custom service into another custom service

Now that I have my script files referenced in my view template, I am having trouble injecting the first one into the second one.
If I unplumb the dependency that LearnerService has on SCORMService, everything displays according to plan, but is of course nonfunctional because LearnerService relies on SCORMService to accomplish its purpose. When I try to actually use my SCORMService within my LearnerService, I get Michael Bay explosions and sad trombones.
So, I'm using ngRoute. That might be important; maybe not.
I'll list my app.js, my script ordering in index.html, learnerServices.js, SCORMServices.js, and controllers.js
app.js
'use strict';
var app = angular.module('client', [
'ngRoute'
,'controllers'
,'services.proxy.scorm'
,'services.proxy.lms'
]);
index.html
...
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="js/SCORMService.js"></script>
<script src="js/LearnerServices.js"></script>
</head>
<body>
<div class="view-container">
<div ng-view class="view-frame"></div>
</div>
</body>
</html>
LearnerServices.js
'use strict';
var learnerServices = angular.module('services.proxy.lms',['scorm-service']);
learnerServices.factory('LearnerService', [ 'scorm-service', function(){
return true;
}]);
SCORMService.js
'use strict';
var services = angular.module('services.proxy.scorm', []);
services.factory('scorm-service',function(){
var foo = {};
foo.bar = "snazzy jazzy";
return foo;
});
I seem to be attempting to corner the market on stupid mistakes today. Can anyone see what stupid mistake I did this time?
This line should be:
var learnerServices = angular.module('services.proxy.lms',['services.proxy.scorm']);
Notice in your code you are saying the module has a dependency on scorm-service however the dependency for the module is on services.proxy.scorm
Load your dependencies first in your html. That'll help.

How might I move AngularJS Routes into separate file

I was curious if anybody was familiar with separating routes from the main app config function. My route list is getting quite large and I wanted to move them into a separate file and load them into the main config. I have seen this done before but I cannot remember or find where I saw it. Any help would be appreciated.
You can (and should !) use AngularJS modules to separate your application into modules.
Then, each module can define its own routes (with its own .config).
Then, in your main module (usually "app"), you just need to require them as dependencies and you're set to go.
angular.module('blog', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
...
}];
angular.module('app', ['blog', 'user']);
Then you can have each module in its own file.
You can put your config function in a separate file easily:
App-config.js
angular.module('app').config(function(...){...});
Just make sure you include the module definition before you include App-config.js.
App-module.js
angular.module('app',[...]).controller(...).etc
It's easy to set up config file separately. There are few other ways to set this up, and I played around with those structure for config; this seems to work for me the best. Enjoy!
---> myApp.html
<html lang="en" ng-app="myApp">
<head>
<script src="lib/angular.min.js" type="text/javascript"></script>
<script src="lib/angular-route.min.js" type="text/javascript"></script>
<script src="js/app.js" type="text/javascript"></script>
<script src="js/controller.js" type="text/javascript"></script>
...
</head>
<body ng-controller="MainCtrl">
<!-- /* Using ng-view with routeProvider to render page templates */ -->
<div data-ng-view></div>
</body>
</html>
----> app.js
'use strict';
angular.module('myApp', [
'ngRoute',
'ngAnimate',
'myApp.controllers'
]).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/page1', {
templateUrl : 'partials/page1.html',
controller : 'page1Controller'
});
$routeProvider.when('/page2', {
templateUrl : 'partials/page2.html',
controller : 'page2Controller'
});
$routeProvider.when('/images', {
templateUrl : 'partials/page3.html',
controller : 'page3Controller'
});
$routeProvider.otherwise({redirectTo: '/page1'});
}]);
--->controller.js
angular.module('myApp.controllers', ['myModules'])
.controller('mainCtrl', function($scope) {
...
})
.controller('page1', function($scope) {
...
})
.controller('page2', function($scope) {
...
})
.controller('page3', function($scope) {
...
});

Resources