AngularJS Routing Not Working As Expected - javascript

I'm new to AngularJS and very lost at this point. I am trying to learn from this code:
http://plnkr.co/edit/dd8Nk9PDFotCQu4yrnDg?p=preview
script.js:
// create the module and name it scotchApp
var scotchApp = angular.module('scotchApp', ['ngRoute']);
// configure our routes
scotchApp.config(function($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
});
// create the controller and inject Angular's $scope
scotchApp.controller('mainController', function($scope) {
// create a message to display in our view
$scope.message = 'Everyone come and see how good I look!';
});
scotchApp.controller('aboutController', function($scope) {
$scope.message = 'Look! I am an about page.';
});
scotchApp.controller('contactController', function($scope) {
$scope.message = 'Contact us! JK. This is just a demo.';
});
My index.html file includes
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
I have it set up on a local environment. I can load the main page but the routing only changes the URL, nothing else. Any ideas what could be causing this?

When you say only Url is called and page is not rendered means, ngroute works fine. One thing you need to make sure is that all html files reside under pages directory.
Also there should be <ng-view> tag inside index.html page
The best example is the plunker you are referring to.

I found the solution to my problem. I had to add
app.use(express.static(__dirname ));
To my node server script. I don't understand why this was needed, though.

Related

$locationProvider.html5Mode(true) not working with tomcat

I am trying to remove "#" from the URL of my Angular JS app. It is currently deployed on tomcat server on my location machine and accessible through a custom port like :8081.
I looked at various articles and also different threads on stackoverflow to fix the issue. But all went in vain.
I am getting following error (from developer console of the browser) when I try to access the home page of my app using localhost:8081/myAngularApp.
Uncaught Error: [$injector:modulerr] Failed to instantiate module myAngularApp due to:
TypeError: Cannot read property 'html5Mode' of undefined
at http://localhost:8081/myAngularApp/js/angularMyApp.js:34:31
.....
.....
If I remove $locationProvider.html5Mode({...}); then I am able to access the application with a hash like http://localhost:8081/myAngularApp/#/
Here is the snippet from my JS file which configures Angular Module (myAppMain.js) :
...
...
myAngularApp.config([ '$routeProvider', '$locationProvider',
function($routeProvider, $routeParams, $locationProvider) {
$routeProvider
// route for the login page
.when('/login', {
templateUrl : 'pages/login.html',
controller : 'loginController'
})
// route for the dashboard page
.when('/dashboard', {
templateUrl : 'pages/dashboard.html',
controller : 'dashboardController'
});
// route for the FAQ page
.when('/faq', {
templateUrl : 'pages/faq.html',
controller : 'faqController'
})
// route for the About us page
.when('/aboutUs', {
templateUrl : 'pages/aboutUs.html',
controller : 'aboutUsController'
});
.otherwise({redirectTo: '/'
});
if(window.history && window.history.pushState){
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
}
}
]);
...
...
I have already added base href="/" tag in the head tag of index.html.
I am not sure if I have to do some changes at tomcat end to make it working or there is some other problem..
Please help.
Thanks
myAngularApp.config([ '$routeProvider', '$locationProvider', function($routeProvider, $routeParams, $locationProvider) {
should be
myAngularApp.config([ '$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {

AngularJS "Argument 'mainController' is not a function"

im new to Angular and need some help.
I'm trying to setup a basic directory structure where i have modules and controllers in seperate JS-files. However, when i do this i get the error stated in the posts title.
The module looks like this:
var myApp = angular.module('myApp', ['ngRoute']);
Controllers like this:
myApp.controller('mainController', function ($scope) {
$scope.message = 'Test message';
});
And routes:
myApp.config(function ($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl: 'components/home/home.html',
controller: 'mainController'
})
// route for the about page
.when('/about', {
templateUrl: 'components/about/about.html',
controller: 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl: 'components/contact/contact.html',
controller: 'contactController'
});
});
Then in my HTML i use ng-app="myApp" and ng-controller="mainController" and trying to write out: {{message}} from it. But it doesn't work.
If i put all the angular code in the same JS-file, then it works. But not when they are seperated.
Help and an explaination is highly appreciated!
As the comments have suggested, this error is usually caused my a missing reference to the file that contains your mainController. Your index.html should contain script references to your javascript files. Here is an example from one of my small apps:
<!-- Custom scripts -->
<script src="/app.js"></script>
<!-- Controllers -->
<script src="/login/loginCtrl.js"></script>
<script src="/home/homeCtrl.js"></script>
<!-- Directives -->
<script src="/common/directives/pageHeader/pageHeader.directive.js"></script>
<script src="/common/directives/footerGeneric/footerGeneric.directive.js"></script>
<script src="/common/directives/queryBuilder/queryBuilder.directive.js"></script>
<script src="/common/directives/scroll/infScroll.js"></script>
All of this should come after including jquery and angular. Additionally (I don't know where you include app.js successfully, you may have already done this) you need to direct AngularJS routes to the index.html file from your express server (assuming express/node backend) in your main app file like so:
app.use(express.static(path.join(__dirname, 'app_client')));
app.use(function (req,res){
res.sendfile(path.join(__dirname, 'app_client', 'index.html'))
});
I hope this was helpful. If you post the code where you attempt to include your application and controller then I can provide a more detailed answer.

Multiple routes sharing one controller, how about different titles?

I'm re-writing an app using angularjs.
Until today each route of the app had each own controller and a title as well for the prowser using a service like that:
myApp.factory('PageTitle', function(){
var title = 'Default title';
return {
title: function() { return title; },
setTitle: function(newTitle) { title = newTitle; }
};
});
which the i use in the controller like that:
PageTitle.setTitle(TitleVariable);
That worked perfectly until now.
I need as i said to re-write my app to have only one controller for all the routes.
So i'm trying to run a function looking at the route change with the current route path to update the title (which i forgot to mention is a dynamic information, so i cannot add a title variable in the routes file i guess) but it just not working.
What is the correct way to achieve that?
My routes looking that that:
myApp.config([
'$routeProvider',
'$locationProvider',
function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(false).hashPrefix('!');
$routeProvider
// route for the home page
.when('/', {
templateUrl : 'views/homepage.html'
})
// route for the home page
.when('/home/:pageSlug/', {
templateUrl : 'views/homepage.html'
})
etc.
I'm calling the controller in the index.html file on header like:
<html data-ng-app="myApp" data-ng-controller="appCtrl">
And i'm getting the title like that:
<title data-ng-bind="PageTitle.title()"></title>

$routeProvider.when(..) not catching all URLs

setup: jade, angular, express, node.
In my routeProvider of angular, I am having some issues. I am requesting a url with a parameter which it is not catching.
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
//... omitted some url/pages here
//start of SPA
.when('/dashboard/', {
templateUrl: 'partials/index',
controller: 'dashIndexCtrl'
})
.when('/dashboard/class/:id',{
templateUrl: 'partials/class',
controller: 'classCtrl'
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
}]);
When I call localhost/dashboard/class/TEST
I get redirected to root.
I declare my routes on the server side as follows:
app.get('/dashboard', routes.dashboard);
app.get('/dashboard/partials/:name', routes.partials);
app.get('/api/class/:id', api.classGet);
My controller name matches up with the routeProvider. In which case the controller code goes as follows:
app.controller('classCtrl', function($scope, $http, $routeParams){
$http.get('/api/class/' + $routeParams.id)
.success(function(dataJson){
console.log(dataJson);
});
});
Why is routeProvider missing this url? I have set breakpoints within my controller so I am certain it is not being called. Also my partials/class.jade is not being called. Let me know if you need anymore code or directory information. Thanks in advance.
After further investigation:
If I go: localhost/dashboard/partials/class it will load that jade file. So it is definitely the controller.
Directory structure, I believe this is my issue now....
+---\
| +---\views
| +---index.jade
| +---dashboard.jade
| +---\partials
| +---index.jade
| +---class.jade
Take a look into console and observe that AngularJS tries to load templates from /partials/index then from /dashboard/partials/index
Solution
set templateUrl path as /dashboard/partials/index in config section.
Reason: angular-route.js
templateUrl = $sce.getTrustedResourceUrl(templateUrl);
if (angular.isDefined(templateUrl)) {
next.loadedTemplateUrl = templateUrl;
template = $http.get(templateUrl, {cache: $templateCache}).
then(function(response) { return response.data; });
}
There is no concatenation templateUrl with route path – just load tempalteUrl from Angular root of application.

AngularJS relative url routing issue

I have my backend web framework loading my AngularJS app with following URL
http://localhost/New/Alpha/App
I also have it set up so that anything after App will still load the same thing
http://localhost/New/Alpha/App/home
http://localhost/New/Alpha/App/settings
...
I'm trying to make my AngularJS app to work in the way that it would pick up the bit of URL after App and load a controller/template accordingly. I have a problem with routing in my AngularJS app though
var main = angular.module("main", ["ui.bootstrap", "ngRoute"]);
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: "fail"
});
$locationProvider.html5Mode(true);
});
main.controller("mainController", function($scope) {
console.log("home")
});
If I try this URL
http://localhost/New/Alpha/App/home
it changes the URL to
http://localhost/fail
instead of leaving the URL as it is and loading the template/controller. If however I change the config and give it a full relative URL it does work as supposed to
.when("/New/Alpha/App/home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
My problem is, that the part of URL before App - /New/Alpha cannot be hardcoded in. It could be /New/Beta, /New/Gamma, etc.
Is what I want to do possible at all without hardcoding the full relative URL match?
UPDATE Sorry, forgot to mention that the number of URL segments before App can change, as in it could be /New/Beta/App and it also could be /New/Another/Beta/App. I don't suppose something like */App or /New/*/App is possible instead of /New/:placeholder/App?
Will this work for you?
var main = angular.module("main", ["ui.bootstrap", "ngRoute"]);
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when("/New/:greek/App/home", {
templateUrl: "assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: "fail"
});
$locationProvider.html5Mode(true);
});
main.controller("mainController", function($scope) {
console.log("home")
});
You could then retrieve the greek with $routeParams.greek from within your controller.
The general solution to this problem is to have the server pass the app URL to your client-side code. In other words, use server-side code to dynamically write the equivalent of the following on the page:
var appUrl = '/New/Alpha/App';
Then setting up the route provider becomes:
main.config(function($routeProvider, $locationProvider) {
$routeProvider
.when(appUrl + "/home", {
templateUrl: "/assets/tpl/home.html",
controller: "mainController"
})
.otherwise({
redirectTo: appUrl + "/fail"
});
$locationProvider.html5Mode(true);
});
That way the knowledge of the application base URL lives in one place — server-side (which makes sense as only the server is in a position to truly know, if you think about it).
In your specific case, if the application base URL is implicit in the URL structure, you could calculate the following client-side:
var appUrl = window.location.pathname.match(/^\/New\/.*\/App/);
Needs work, but you get the idea. Then you can set up the route provider exactly as above.

Categories

Resources