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.
Related
I am trying to set up a project using gulp and browser sync with angularjs. I cannot get browser sync to work correctly when I use the ng-view tag in my index.html file. This is the error I get in my browser console when I run browser sync:
Uncaught TypeError: Cannot read property 'data1457531805746' of null
coming from browser-sync-client.2.11.1.js:204 It works as expected, page loads fine, when ng-view/ngRoute is not used.
These are my files:
./gulpfile.js
// Spin up a server
gulp.task('browserSync', function() {
browserSync.use(spa({
selector: "[ng-app]" //Only needed for angular apps
}));
browserSync.init({
port: 8080,
server: {
baseDir: path.src
}
})
});
// Watch for changes in files
gulp.task('watch', ['browserSync'], function() {
// Watch .js files -- removed for brevity
});
// Default Task
gulp.task('default', ['watch']);
./app/controllers/controllers.js
'use strict';
/* Controllers */
var dc4SearchControllers = angular.module('dc4SearchControllers', []);
dc4SearchControllers.controller('CompanySearchCtrl', ['$scope', '$http',
function($scope, $http){
$scope.test = 'Hello, world!';
}]);
./app/index.html
<html ng-app="dc4SearchApp">
<head>
<link href="/bower_components/webui-core/dist/webui-core.min.css" rel="stylesheet">
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
<script src="/bower_components/angular/angular.min.js"></script>
<script src="/bower_components/angular-route/angular-route.min.js"> </script>
<script src="/bower_components/lodash/lodash.min.js"></script>
<script src="/bower_components/webui-core/dist/webui-core.min.js"></script>
<script src="app.js"></script>
<script src="controllers/controllers.js"></script>
</head>
<body ng-view>
</body>
</html>
./app/app.js
'use strict';
/* App Module */
var dc4SearchApp = angular.module('dc4SearchApp', [
'ngRoute',
'dc4SearchControllers'
]);
dc4SearchApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/company-search', {
templateUrl: 'views/company-search.html',
controller: 'CompanySearchCtrl'
}).
otherwise({
redirectTo: '/company-search'
});
}]);
./app/views/company-search.html
<div ng-controller="CompanySearchCtrl">
{{test}}
<div class="spinner spin"> </div>
</div>
I am hoping this is just something silly and easy that I am over looking and haven't tried yet! Thanks in advance.
"Browsersync works by injecting an asynchronous script tag right after the body tag during initial request. In order for this to work properly the body tag must be present. Alternatively you can provide a custom rule for the snippet using snippetOptions"
https://www.npmjs.com/package/browser-sync
It seems Browsersync is reloading the body tag. Have you tried moving the ng-view to another child div ?
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
I am trying to create a simple Angular app and I have recently added a router in route.js. For some reason the association isn't being made between mainCtrl and someview.html The reason I know this is because the view isn't being injected in <div ng-view></div> Anyone have any idea why?
My folder structure is the following
root
------/app
----------routes.js
----------/views
-----------------someview.html
------/public
---------mainCtrl.js
---------index.html
server.js
mainCtrl.js
angular.module('LiveAPP',[])
.controller('MainCtrl', function($scope) {
$scope.Artists = [
{name:"Blink 182",age:14},
{name:"Led Zeppelin",age:12},
{name:"Lil Wayne",age:11}
];
$scope.number = 100;
});
someview.html
<div>{{number}}</div>
route.js
angular.module('LiveAPP', ['ngRoute'])
.config(function($routeProvider, $httpProvider) {
$routeProvider
.when('/', {
templateUrl : '/views/someview.html',
controller : 'MainCtrl'
})
});
index.html
<!doctype html>
<html ng-app='LiveAPP'>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js">
</script>
<link rel="stylesheet" href="http://yui.yahooapis.com/pure/0.6.0/pure-min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28//angular-route.min.js"></script>
<script src="mainCtrl.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
server.js
var express = require('express');
var app = express();
app.use(express.static(__dirname + '/public'));
app.listen(3000);
console.log("Listening at 3000")
angular.module('LiveAPP',[])
.controller('MainCtrl', function($scope) {
Here, you define a module LiveAPP, that doesn't depend on any other module, and add a controller to this module.
angular.module('LiveAPP', ['ngRoute'])
.config(function($routeProvider, $httpProvider) {
And here, you redefine, once again, a module with the same name, depending on ngRoute. But since you're redefining it, you effectively overwrite the previously defined module and all its components.
A module must be defined once, and only once.
I don't know much about express, but I also don't understand why all your files are not under public, since that is apparently the directory that the web server serves.
Hello I'm trying a simple application with Angular and UI-Router...
But for some reason, it's not working at all.
In chrome, there is no error in the console, but there is even no output at all
Maybe some one has some clue on what's happening... I definitely have no idea.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<script src="/Scripts/angular.min.js"></script>
<script src="/Scripts/angular-ui-router.js"></script>
</head>
<body>
<div>
Route 1
<div ui-view="viewSidebar"></div>
<div ui-view="viewContent"></div>
</div>
<script>
var app = angular.module('app', ['ui.router']);
app.config(
['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/media/list');
$stateProvider.state('mediaList', {
views: {
url: "/media/list",
'viewSidebar': {
template: '<p>SideBar</p>',
controller: 'SidebarControllerView'
},
'viewContent': {
template: '<p>Thumb view</p>',
controller: 'MediaControllerView'
}
}
});
}]);
app.controller('MediaControllerView', ['$scope', MediaControllerView]);
app.controller('SidebarControllerView', ['$scope', SidebarControllerView]);
function MediaControllerView($scope) {
$scope.model = 1;
};
function SidebarControllerView($scope) {
$scope.model = 1;
};
</script>
</body>
</html>
There is a working plunker
One important wrong setting is the URL. It does not belong to the view, but to the state:
...
$stateProvider.state('mediaList', {
// url belongs to the state
url: "/media/list",
views: {
// url does not belong to the views
// url: "/media/list",
'viewSidebar': {
template: '<p>SideBar</p>',
controller: 'SidebarControllerView'
},
'viewContent': {
template: '<p>Thumb view</p>',
controller: 'MediaControllerView'
}
}
});
...
Check it here
And also, as DTing spotted we have to provide ng-app:
<html ng-app="app" ng-strict-di>
...
NOTE: ng-strict-di is not a must but... it is a must - to avoid later issues...
if this attribute is present on the app element, the injector will be created in "strict-di" mode. This means that the application will fail to invoke functions which do not use explicit function annotation (and are thus unsuitable for minification), as described in the Dependency Injection guide, and useful debugging info will assist in tracking down the root of these bugs.
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) {
...
});