AngularJS controller not properly loaded during ng-Route otherwise() - angularjs

I'm learning an example of a single page application using angularjs. Here's the relevant code:
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"/>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.js"></script>
<script>
var app = angular.module('app', ['ngRoute']);
app.config(function ($routeProvider) {
// configure the routes
$routeProvider
.when('/', {
// route for the home page
templateUrl: 'pages/home.html',
controller: 'homeController'
})
.when('/about/', {
// route for the about page
templateUrl: 'pages/about.html',
controller: 'aboutController'
})
.when('/contact/', {
// route for the contact page
templateUrl: 'pages/contact.html',
controller: 'contactController'
})
.otherwise({
// when all else fails
templateUrl: 'pages/routeNotFound.html',
controller: 'notFoundController'
});
});
app.controller('homeController', function ($scope) {
$scope.message = 'Welcome to my home page!';
});
app.controller('aboutController', function ($scope) {
$scope.message = 'Find out more about me.';
});
app.controller('contactController', function ($scope) {
$scope.message = 'Contact us!';
});
app.controller('notFoundController', function ($scope) {
$scope.message = 'There seems to be a problem finding the page you wanted';
$scope.attemptedPath = $location.path();
});
</script>
</head>
<body ng-controller="homeController">
<header>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">My Website</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><i class="fa fa-home"></i> Home</li>
<li><i class="fa fa-shield"></i> About</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul>
</div>
</nav>
</header>
<div id="main">
<!-- this is where content will be injected -->
<div ng-view></div>
</div>
</body>
</html>
routeNotFound.html
<div class="jumbotron text-center">
<h1>This is not good</h1>
<p>{{message}}</p>
<p class="has-error">{{attemptedPath}}</p>
</div>
When I click on Home or About or Contact the page renders correctly. But if I visit any other URL, routeNotFound.html is injected correctly to div[ng-view] but the data is not bound. I get:
This is not good
{{message}}
{{attemptedPath}}
It seems notFoundController is not correctly made available to the view when .otherwise() is called inside route. $scope.message and $scope.attemptedPath is not bound to the view.

You are missing $locationService injection in your notFoundController
app.controller('notFoundController', function ($scope,$location /*<--- location injected here*/) {
$scope.message = 'There seems to be a problem finding the page you wanted';
$scope.attemptedPath = $location.path();
});
Here is a full sample:
var app = angular.module('app', ['ngRoute']);
app.config(function ($routeProvider) {
// configure the routes
$routeProvider
.when('/', {
// route for the home page
template: '<h1>My page home</h1><br />{{message}}',
controller: 'homeController'
})
.when('/about/', {
// route for the about page
template: '<h1>My page about</h1><br />{{message}}',
controller: 'aboutController'
})
.when('/contact/', {
// route for the contact page
template: '<h1>My page contact</h1><br />{{message}}',
controller: 'contactController'
})
.otherwise({
// when all else fails
template: '<h1>Not found page</h1><br />{{message}}',
controller: 'notFoundController'
});
});
app.controller('homeController', function ($scope) {
$scope.message = 'Welcome to my home page!';
});
app.controller('aboutController', function ($scope) {
$scope.message = 'Find out more about me.';
});
app.controller('contactController', function ($scope) {
$scope.message = 'Contact us!';
});
app.controller('notFoundController', function ($scope,$location) {
$scope.message = 'There seems to be a problem finding the page you wanted';
$scope.attemptedPath = $location.path();
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css"/>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-route.js"></script>
<script>
</script>
</head>
<body ng-controller="homeController">
<header>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">My Website</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><i class="fa fa-home"></i> Home</li>
<li><i class="fa fa-shield"></i> About</li>
<li><i class="fa fa-comment"></i> Contact</li>
<li><i class="fa fa-comment"></i> Not found</li>
</ul>
</div>
</nav>
</header>
<div id="main">
<!-- this is where content will be injected -->
<div ng-view></div>
</div>
</body>
</html>

Related

AngularJS routing: Views are not getting updated

I am learning how to implement routing in AngularJS. Everything else is working fine but the views are not getting updated when I click on the navigation.
How can I achieve the desired functionality in the application? I want the navigation to take us to the desired pages without refreshing the page and that's quite obvious.
Here is the code.
Index.html
<!DOCTYPE html>
<html ng-app="routingApp">
<head>
<title>AngularJS routing</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.7/angular-route.js"></script>
<script src="script.js"></script>
</head>
<body ng-controller="routingAppController">
<!-- Header and Navigation -->
<header>
<nav class= "navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Angular Routing App</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
</nav>
</header>
<!-- Main Body where content will be injected -->
<div id="main">
<div ng-view></div>
</div>
</body>
</html>
Script.js
(function(){
'use strict';
var app = angular.module('routingApp', ['ngRoute']);
app.config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl : 'pages/home.html',
controller : 'routingAppController'
})
.when('/about', {
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
.when('/contact', {
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
});
app.controller('routingAppController', function($scope){
$scope.message = "This will get updated for sure!";
});
app.controller('aboutController', function($scope){
$scope.message = "This is the about page and it looks awesome!";
});
app.controller('contactController', function($scope){
$scope.message = "This is the contact page!";
});
})();
One of the pages
<div class="jumbotron text-center">
<h1>Home Page</h1>
<p>{{ message }}</p>
</div>

Angular route is not showing the view

I want to use routeProvider in ngRoute in angularjs to view my home.html or delete.html or add.html
app.js
var app = angular.module('MyApp', ['ngRoute']);
MyApp.config([
'$routeProvider',
function($routeProvider) {
$routeProvider
.when('/Add', {
templateUrl: 'html/add.html',
controller: 'AddController'
})
.when('/Edit', {
templateUrl: 'html/edit.html',
controller: 'EditController'
})
.when('/Delete', {
templateUrl: 'html/delete.html',
controller: 'DeleteController'
})
.when('/Home', {
templateUrl: 'html/home.html',
controller: 'HomeController'
})
.otherwise({
redirectTo: '/Home'
});
}
]);
MyApp.controller('AddController', function($scope) {
$scope.message = "In add view"
});
MyApp.controller('DeleteController', function ($scope) {
$scope.message = "In delete view"
});
MyApp.controller('EditController', function ($scope) {
$scope.message = "In edit view"
});
MyApp.controller('HomeController', function ($scope) {
$scope.message = "In home view"
});
index.html
<!DOCTYPE html>
<html ng-app="MyApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<!-- bootstrap css -->
<link href="Content/bootstrap.min.css" rel="stylesheet"/>
<!-- Jquery js -->
<script src="Scripts/jquery-1.9.1.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-route.min.js"></script>
<script src="Scripts/internal/app.js"></script>
</head>
<body>
<div class="container">
<nav role="navigation" class="navbar navbar-inverse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="">Add</li>
<li class="">Edit</li>
<li class="">Delete</li>
</ul>
</nav>
<div ng-view>
</div>
<!-- Footer -->
<h3 style="margin-top: 40px;" class="text-center text-info">Single Page App</h3>
</div>
</body>
</html>
When I run my application, and click on any of the links, it gives me this url: http://localhost:51285/html/#!Edit
And in the body is this...
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
In the sample that I am following, it doesn't have that error it just changes to the message.
you have some mistake in your code :
in your html:using Add
2.in your app.js:instead of MyApp.config or MyApp.controller use app.config and app.controller.MyApp is name of your app but you must use variable that your app stored on it.
follwing will working:
your html:
<!DOCTYPE html>
<html ng-app="MyApp" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<!-- bootstrap css -->
<link href="Content/bootstrap.min.css" rel="stylesheet" />
<!-- Jquery js -->
<script src="Scripts/jquery-1.9.1.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/angular-route.min.js"></script>
<script src="internal/app.js"></script>
</head>
<body>
<div class="container">
<nav role="navigation" class="navbar navbar-inverse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li class="">Add</li>
<li class="">Edit</li>
<li class="">Delete</li>
</ul>
</nav>
<div ng-view></div>
<!-- Footer -->
<h3 style="margin-top: 40px;" class="text-center text-info">Single Page App</h3>
</div>
</body>
</html>
your app:
var app = angular.module('MyApp', ['ngRoute']);
app.config([
'$routeProvider',
function ($routeProvider) {
$routeProvider
.when('/Add', {
templateUrl: 'html/add.html',
controller: 'AddController'
})
.when('/Edit', {
templateUrl: 'html/edit.html',
controller: 'EditController'
})
.when('/Delete', {
templateUrl: 'html/delete.html',
controller: 'DeleteController'
})
.when('/Home', {
templateUrl: 'html/home.html',
controller: 'HomeController'
})
.otherwise({
redirectTo: '/Home'
});
}
]);
app.controller('AddController', function ($scope) {
$scope.message = "In add view";
});
app.controller('DeleteController', function ($scope) {
$scope.message = "In delete view";
});
app.controller('EditController', function ($scope) {
$scope.message = "In edit view";
});
app.controller('HomeController', function ($scope) {
$scope.message = "In home view";
});
I hope it could be ralted with configuration. Please check the link below! Angular force an undesired exclamation mark in url

Angular routing didn't work

I don't know why angular routing didn't work with me. I revised the code 10 times and I couldn't find the solution.
My index page is like -
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title></title>
<meta charset="utf-8" />
<link href="Content/bootstrap.css" rel="stylesheet" />
<script src="scripts/jquery-1.9.0.js"></script>
<script src="scripts/bootstrap.js"></script>
<script src="scripts/angular.js"></script>
<script src="scripts/angular-route.js"></script>
<script src="demo.js"></script>
</head>
<body>
<div class="container">
<nav style="background-color:darkslateblue" role="navigation" class="nav navbar-inverse">
<ul class="nav navbar-nav">
<li class="active">home</li>
<li>add</li>
<li>edit</li>
<li>delete</li>
</ul>
</nav>
<ng-view>
</ng-view>
<h3 style="font-size:small" class="text-center text-info">developed by Mr-Mohammed Elwany</h3>
</div>
</body>
</html>
and Javascript page like
/// <reference path="C:\Users\elwany\documents\visual studio 2015\Projects\spaapplication\spaapplication\scripts/angular.js" />
var myApp = angular.module("myApp", ['ngRoute']);
myApp.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/add', {
templateUrl: 'Views/add.html',
controller:'addController'
}).
when('/edit', {
templateUrl: 'Views/edit.html',
controller: 'editController'
}).
when('/delete', {
templeteUrl: 'Views/delete.html',
controller: 'deleteController'
}).
when('/home', {
templateUrl: 'Views/home.html',
controller: 'homeController'
}).
otherwise({ redirectTo: '/home' });
}]);
myApp.controller("addController",function ($scope) {
$scope.message = "in Add view Controller";
});
myApp.controller("editController",function ($scope) {
$scope.message = "in edit view Controller";
});
myApp.controller("deleteController",function ($scope) {
$scope.message = "in delete view Controller";
});
myApp.controller("homeController",function ($scope) {
$scope.message = "in home view Controller";
});
I have 4 html pages in "Views" folder their name is "add","edit","delete","home" and they have the same content.
<div class="row jumbotron">
<h2>{{message}}</h2>
</div>
Please I want to know why it didn't work.
Actually your code is correct but Angular applications work properly on client server architecture.
Kindly Run your application using a local server. There is no need for any Tomcat server. You can easily download a Google Chrome Plugin "Web server for Chrome". here- https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb?hl=en
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootswatch/3.3.7/yeti/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.2/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-route.js"></script>
<script>
var app = angular.module("myApp", ["ngRoute"]);
app.controller()
app.config(function($routeProvider) {
$routeProvider
.when('/abc', {
'template': "This is the ABC page"
})
.when('/Home', {
'template': "This is the home page"
})
.when('/About', {
'template': "This is the About page"
})
.when('/Contact', {
'template': "This is the Contact page"
})
.when('/Service', {
'template': "This is the Service page"
})
})
</script>
</head>
<body>
<div class="container-fluid">
<div class="row">
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="#">Routing App</a>
</div>
<ul class="nav navbar-nav">
<li>Abc</li>
<li>About us</li>
<li>Services</li>
<li>Contact</li>
<li>Contact</li>
</ul>
</div>
</nav>
</div>
<div ng-view></div>
</div>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js">
</script>
<script src="script.js"></script>
</html>

How to get AngularJS routing to maintain state?

I'm getting up to speed with AngularJS routing and have created this example which works.
However, I understood that if on page "home" I type in a text into the input box, then click on page "about" and then come back to "home", the text would still be in the input box, i.e. would have maintained the state.
Is this not the case, and if not, is there a way to maintain state in forms on pages which the user navigates away from?
home.htm
<div class="jumbotron">
<h1>Home</h1>
<p>{{subtitle}}</p>
</div>
<input ng-model="message"/>
index.htm
<html ng-app="mainApp">
<head>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-route.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" rel="stylesheet" />
<style type="text/css">
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
a:focus {
outline: none;
}
</style>
</head>
<body ng-cloak ng-controller="mainController">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<div class="navbar-brand">AngularJS Routing</div>
</div>
<div>
<ul class="nav navbar-nav">
<li><i class="fa fa-home"></i> Home</li>
<li><i class="fa fa-shield"></i> About</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul>
</div>
</div>
</nav>
<div class="col-lg-12">
<div ng-view></div>
</div>
<script>
var mainApp = angular.module('mainApp', ['ngRoute']);
mainApp.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'pages/home.htm',
controller: 'mainController'
})
.when('/about', {
templateUrl: 'pages/about.htm',
controller: 'aboutController'
})
.when('/contact', {
templateUrl: 'pages/contact.htm',
controller: 'contactController'
})
.otherwise({
redirectTo: '/'
});
});
mainApp.controller('mainController', function ($scope) {
$scope.subtitle = 'the home page';
$scope.message = '';
});
mainApp.controller('aboutController', function ($scope) {
$scope.subtitle = 'the about page';
});
mainApp.controller('contactController', function ($scope) {
$scope.subtitle = 'the contact page';
});
</script>
</body>
</html>
Controllers do not maintain state, they are created and destroyed every time you go through the route. You will need to implement a service that you can use to store your data and then have a means to send the data to the service when you want to persist it. Controller have a '$destroy' event that occurs right before the scope is released that you can hook.
mainApp.service('myData', function() {
this.message = '';
})
.controller('mainController', function($scope, myData) {
$scope.message = myData.message;
$scope.$on("$destroy", function() {
myData.message = $scope.message;
});
});

Active Class Based On Selected Menu

I'm learning angular and try to create a navbar menu and set 'active' class based on current page.
index.html
<html lang="en" data-ng-app="Afe" class="no-js">
<head>
<!-- code omitted.. -->
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav" data-ng-init="activeMenu='AfeCoverPage'">
<li data-ng-class="{active: activeMenu=='AfeCoverPage'}" data-ng-click="activeMenu='AfeCoverPage'">AFE Cover Page</li>
<li data-ng-class="{active: activeMenu=='AfeCostEstimate'}" data-ng-click="activeMenu='AfeCostEstimate'">AFE Cost Estimate</li>
<li data-ng-class="{active: activeMenu=='AfeVariance'}" data-ng-click="activeMenu='AfeVariance'">AFE Variance</li>
</ul>
</div>
</div>
</nav>
<div data-ng-view=""></div>
<!-- code omitted.. -->
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
</body>
</html>
app.js
angular.module('Afe', ['ngRoute', 'Afe.controllers']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/AfeCoverPage', { templateUrl: 'partials/AfeCoverPage.html', controller: 'AfeCoverPageCtrl' });
$routeProvider.when('/AfeCostEstimate', { templateUrl: 'partials/AfeCostEstimate.html', controller: 'AfeCostEstimateCtrl' });
$routeProvider.when('/AfeVariance', { templateUrl: 'partials/AfeVariance.html', controller: 'AfeVarianceCtrl' });
$routeProvider.otherwise({ redirectTo: '/AfeCoverPage' });
}]);
controllers.js
angular.module('Afe.controllers', []).
controller('GlobalCtrl', ['$scope', function ($scope) {
}]).
controller('AfeCoverPageCtrl', ['$scope', function ($scope) {
}]).
controller('AfeCostEstimateCtrl', ['$scope', function ($scope) {
}]).
controller('AfeVarianceCtrl', ['$scope', function ($scope) {
}]);
Currently it's working, when Afe Cover Page menu is clicked, the <li> element will have 'active' class, but I'm not sure whether using ng-click is the right way. The code seems to be duplicated. Could anyone show me the best way to do it?
You could just use the $location service and a function in your ng-class directive that returns a bool if it matches the current path.
<div class="collapse navbar-collapse" ng-controller="MenuController">
<ul class="nav navbar-nav">
<li data-ng-class="{active: isActive('/AfeCoverPage')}">AFE Cover Page</li>
<li data-ng-class="{active: isActive('/AfeCostEstimate')}">AFE Cost Estimate</li>
<li data-ng-class="{active: isActive('/AfeVariance')}">AFE Variance</li>
</ul>
</div>
With a controller:
.controller('MenuController', function ($scope, $location) {
$scope.isActive = function (path) {
return $location.path() === path;
}
});

Resources