I am working in angularjs, of course, and following are the index.php (after logging in) and mainApp.js (main application after logging in). Here I am using session storage to check whether the current session is valid or not. Moreover, after logging in, the parent page, i.e. the one rendered by index.php is visible along with its navigational bar, but the templates are no where to be found. The google development tools show that the templates have been loaded successfully (i.e. status 200) and one can see the in the network's tab. But the templates are not rendered no matter what you select from navigational bar.
index.php
<!-- main page -->
<?php
$version = time();
?>
<!DOCTYPE html>
<html>
<head>
<!-- CSS (load bootstrap and our custon css files) -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
<style>
.navbar {
border-radius: 0px;
}
ul {
list-style-type: none;
}
</style>
<!-- JS (load angular, ui-router and our custom js file) -->
<script src="http://code.angularjs.org/1.2.13/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<script src="js/mainApp.js"></script>
</head>
<!-- NAVIGATION -->
<body>
<div ng-app="mainApp">
<nav class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<a class="navbar-brand"><strong>DASHBOARD</strong></a>
</div>
<ul class="nav navbar-nav navbar-left">
<li><a ui-sref="home">Home</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown">Client
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a ui-sref="addClient">Add Client</a></li>
</ul>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown">Service
<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a ui-sref="addService">Add Service</a></li>
</ul>
</li>
<li><a ui-sref="about">About</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a ui-sref="logout">Logout</a></li>
</ul>
</nav>
</div>
<!-- MAIN CONTENT -->
<div class="container">
<!-- THIS IS WHERE WE WILL INJECT OUR CONTENT -->
<div ui-view></div>
</div>
</body>
</html>
mainApp.js
var mainApp = angular.module('mainApp', ['ui.router']);
mainApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url:'/',
templateUrl: function (){
if(sessionStorage.username!=="karan" || sessionStorage.password!=="123456"){
return 'templates/login.html';
}
else {
return 'templates/home.html';
}
}
})
.state('addClient', {
url:'/addClient',
templateUrl: function(){
if(sessionStorage.username!=="karan" || sessionStorage.password!=="123456"){
return 'templates/login.html';
}
else{
return 'templates/addClient.html';
}
}
})
.state('addService', {
url:'/addService',
templateUrl: function(){
if(sessionStorage.username!=="karan" || sessionStorage.password!=="123456"){
return 'templates/login.html';
}
else{
return 'templates/addService.html';
}
}
})
.state('about', {
url: '/about',
templateUrl: function (){
if(sessionStorage.username!=="karan" || sessionStorage.password!=="123456"){
return 'templates/login.html';
}
else {
return 'templates/about.html';
}
}
})
.state('logout', {
url: '/login',
templateUrl: function (){
sessionStorage.clear();
return 'templates/login.html';
}
});
});
please tell me if there's any better way instead of using sessions and also help me solve this problem. Thank you.
P.S. on a side note, i am a newbie in angularjs and would appreciate if you can guide me in how to implement login most efficiently , both performance and security wise
One way to handle this situation is adding an interceptor as follows.
mainApp.config(function ($httpProvider) {
$httpProvider.interceptors.push('loginInterceptor');
}).factory('loginInterceptor', function ($q, $window,$rootScope) {
return {
'response': function(response) {
if(sessionStorage.username!=="karan" || sessionStorage.password!=="123456"){
$rootScope.$broadcast("notLoggedIn",{statusCode : 'NOT_LOGGED_IN'});
}
else{
return response;
}
},
'responseError': function(rejection) {
return $q.reject(rejection);
}
}
})
Then handle the message 'notLoggedIn' as follows
mainApp.run(function($state,$rootScope){
$rootScope.$on("notLoggedIn",function(event,message){
$state.transitionTo('login');//Define a state with template url 'templates/login.html';
});
})
Advantage of this approach is, you will not end up checking the login status in every state definitions.
Try using ng-view instead of ui-view and see if that makes a difference, it helped in my case.
Related
I am making a simple Angular application that has an index.html which loads other HTML pages as views based on which navbar item selected; however, the routing is not working as expected. The main.html view is loaded fine, but none of the other views are loaded, and the URL is not what I expect.
The URL that shows up in the browser after an item is selected is localhost:8081/#!/#pageName. I do not know where the '!' is coming from, and there should not be a hash before the pageName. The URL that I am expecting is localhost:8081/#/pageName
app.js:
'use strict';
var app = angular.module('videoGamesApp', ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/rankedLists', {
templateUrl: 'views/rankedLists.html',
controller: 'RankedListsCtrl'
})
.when('/addGame', {
templateUrl: 'views/addGame.html',
controller: 'AddGameCtrl'
})
.when('/contact', {
templateUrl: 'views/contact.html',
controller: 'ContactCtrl'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('MainCtrl', function($scope) {
$scope.message = 'THIS IS THE MAIN PAGE';
});
app.controller('RankedListsCtrl', function($scope) {
$scope.message = 'THIS IS THE RANKED LISTS PAGE';
});
app.controller('AddGameCtrl', function($scope) {
$scope.message = 'THIS IS THE ADD GAME PAGE';
});
app.controller('ContactCtrl', function($scope) {
$scope.message = 'THIS IS THE CONTACT PAGE';
});
index.html:
<!doctype html>
<html ng-app="videoGamesApp">
<head>
<meta charset="utf-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../bower_components/font-awesome/css/font-awesome.css">
</head>
<body ng-controller="MainCtrl">
<header>
<nav class="navbar navbar-inverse">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">GAMING </a>
</div>
<ul class="nav navbar-nav">
<li><i class="fa fa-home"></i> Home</li>
<li><i class="fa fa-trophy"></i> Ranked Lists</li>
<li><i class="fa fa-gamepad"></i> Add a Game</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul>
<div class="col-sm-3 col-md-3 pull-right">
<form class="navbar-form" role="search">
<div class="input-group">
<input type="text" class="form-control" placeholder="Search" name="sr ch-term">
<div class="input-group-btn">
<button class="btn btn-default" type="submit">
<i class="glyphicon glyphicon-search"></i>
</button>
</div>
</div>
</form>
</div>
</div>
</nav>
</header>
<div id="main">
<div ng-view=""></div>
</div>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="scripts/app.js"></script>
</body>
</html>
Why are the other views not loading? Where is the exclamation point coming from in the URL? Why is there a hash before the pageName (I expect one hash, not two).
Why are the other views not loading?
The reason why your views are not loaded is because you hit the route. You use 1.6 angular and expect the behaviour from 1.5. There has been a change in location hash-prefix:
Due to aa077e8, the default hash-prefix used for $location hash-bang
URLs has changed from the empty string ('') to the bang ('!'). If your
application does not use HTML5 mode or is being run on browsers that
do not support HTML5 mode, and you have not specified your own
hash-prefix then client side URLs will now contain a ! prefix. For
example, rather than mydomain.com/#/a/b/c the URL will become
mydomain.com/#!/a/b/c.
If you actually want to have no hash-prefix, then you can restore the
previous behavior by adding a configuration block to you application:
appModule.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix(''); }]); Source
What to do?
1. Set HTML5mode true
$locationProvider.html5Mode(true);
and in html set base in html header:
<base href="/">
Lastly change <a ng-href="#pagename"> to
<a ng-href="pagename">
2. Go back to old behaviour from 1.5 - set hash prefix manually
This will make your app work as you expect in your question.
app.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
Why is there a hash before the pageName?
The way you link is treated as a hashtag anchor tag. Which will scroll down to the current div with the given id. If you fix your problem with one of the above reasons this will be fixed aswell.
I am using Angular $route for nav highlighting, but the highlighting does not show. Here is the code for the navigation...
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body ng-app="myApp">
<div ng-controller="myController" class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li ng-class="{active: $route.current.activetab == 'home'}">Home</li>
<li ng-class="{active: $route.current.activetab == 'audio'}">Audio</li>
<li ng-class="{active: $route.current.activetab == 'bio'}">Artist Bio</li>
<li ng-class="{active: $route.current.activetab == 'contact'}">Contact</li>
</ul>
</div>
</body>
</html>
Here is the code for the AngularJS controller with $route...
app.controller("myController", function($scope,$http, $route) {
$http.post('myform.php')
.then(function successCallback(response){
$scope.detail = response.data;
if($scope.detail){
console.log("success");
} else{
console.log("no data");
}
}, function errorCallback(response) {
console.log("error");
});
$scope.$route = $route;
});
Did you include the js library?
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-route.js"></script>
Did you inject ngRoute into your angular module?
var app = angular.module("myApp", ['ngRoute']);
I've put this code in Html head section:
<script src="lib/smart-menus/jquery.smartmenus.min.js"></script>
<script type="text/javascript">
$(function() {
$('#main-menu').smartmenus({
subMenusSubOffsetX: 1,
subMenusSubOffsetY: -8
});
});
</script>
<link href="lib/smart-menus/sm-core-css.css" rel="stylesheet" />
<link href="lib/smart-menus/sm-blue.css" rel="stylesheet" />
and in body:
<nav id="main-nav" role="navigation">
<div id="main-menu" class="sm sm-rtl sm-blue">
<ul>
<li><a ui-sref="site.home">Home</a></li>
<li ng-repeat="menu in menus">
<a href='#'>{{menu.Title}}</a>
<ul ng-show="getHasSubMenus(menu)">
<li ng-repeat="subMenu in menu.SubMenus">
<a ui-sref="site.shopbycategory({ departmentID: subMenu.DepartmentID , categoryID: subMenu.CategoryID, searchTerm: '' })">
{{subMenu.Title}}
</a>
</li>
</ul>
</li>
<li><a ui-sref="site.contact">Contacts</a></li>
</ul>
</div>
</nav>
in the page controller I have:
function siteController($scope, $location, $rootScope, Account, $state, $stateParams, Site, $timeout) {
$timeout(function () {
$scope.getMenus(function () { // OnSuccess
$('#main-menu').smartmenus('refresh');
});
}, 1);}
Also I included jQuery 1.12 before other scripts. and I can verify that angularjs has added all the menus to the main-menu div using F12 in IE, But nothing appears in the page and I don't get any errors from these codes. Is my code correct?
I changed:
<div id="main-menu" class="sm sm-rtl sm-blue">
<ul>
to:
<ul id="main-menu" class="sm sm-rtl sm-blue">
now top level links work and submenus despite existence not showing.
I have created a simple Single page application with angular js. I have a index page in which the route is defined and the ng-view is called.
Index.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="SPA.Views.index" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="app">
<head runat="server">
<title>SPA</title>
<!-- load bootstrap and fontawesome via CDN -->
<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" />
</head>
<body data-ng-controller="Index as ind">
<form id="form1" runat="server">
<!-- HEADER AND NAVBAR -->
<header>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Angular Routing Example</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li><i class="fa fa-home"></i> Dashboard</li>
<li><i class="fa fa-shield"></i> About</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul>
</div>
</nav>
</header>
<!-- MAIN CONTENT AND INJECTED VIEWS -->
<div id="main">
<!-- angular templating -->
<!-- this is where content will be injected -->
<div ng-view></div>
</div>
</form>
<!-- load angular and angular route via CDN -->
<%--<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>--%>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular-route.js"></script>
<script src="../Controllers/app.js"></script>
</body>
</html>
App.js:
var app = angular.module('app', ['ngRoute']);
// configure our routes
app.constant('routes', [
{
url: '/',
config: {
templateUrl: 'dashboard.aspx',
menuItem: 'MainPage'
}
},
{
url: '/about',
config: {
templateUrl: 'about.aspx',
menuItem: 'aboutPage'
}
},
{
url: '/contact',
config: {
templateUrl: 'contact.aspx',
menuItem: 'contactPage'
}
}
]);
app.config(['$routeProvider', 'routes', '$controllerProvider', function ($routeProvider, routes, $controllerProvider) {
//$controllerProvider.allowGlobals();
app._controller = app.controller;
// Provider-based controller.
app.controller = function (name, constructor) {
$controllerProvider.register(name, constructor);
return (this);
};
routes.forEach(function (route) {
$routeProvider.when(route.url, route.config);
});
}]);
var controllerId = 'Index';
app.controller(controllerId, function ($scope, $location) {
var ind = this;
$scope.openDashboard = function () {
$location.path('/');
}
$scope.openOpportunity = function () {
$location.path('/opportunity');
}
$scope.openContact = function () {
$location.path('/contact');
}
})
I have created three separate aspx pages for each menu and separate .js file (in which controller is defined for each page).
When the page load, it calls dashboard page by default and it throws error as
Error: [ng:areq]
http://errors.angularjs.org/1.3.0-beta.17/ng/areq?p0=dashboardController&p1=not%20a%20function%2C%20got%20undefined
Here, dashboardController is the name of the controller defined in Dashboard page.
Dashboard.aspx:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="dashboard.aspx.cs" Inherits="SPA.Views.dashboard" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.25/angular.min.js"></script>
<script src="../Controllers/dashboard.js"></script>
</head>
<body>
<form id="form1" runat="server">
<div data-ng-controller="dashboardController">
{{message}}
</div>
</form>
</body>
</html>
and the associated controller file is as follows (dashboard.js):
(function () {
var app = angular.module('app');
var controllerId = 'DashboardController';
app.controller(controllerId, function ($scope) {
$scope.message = "Hello!!";
});
})();
The other pages also have the same code and that too provide the above mentioned error when a menu is selected.
When I tried to call 'dashboard.js' file in index.aspx itself, it display the page correctly.
But I don't want to call all the js file at the starting, since in future i will be using a large amount of data to display in each page and hence it might slow down the application.
Please let me know, how I should proceed to get the output by calling the controllers when that particular page is called.
Thanks in advance...
The error is pretty clear - stating dashboardController is not defined. You're attempting to call your controller DashboardController as such
<div data-ng-controller="dashboardController"> <!-- lowercase d -->
var controllerId = 'DashboardController'; // -- capital D
Forget the var and lowercase your controller name as such. Also, remove var app = angular.module('app');. You're overwriting your prior module definition, which you already have in App.js. The entire contents of dashboard.js should be the following
app.controller('dashboardController', function ($scope) {
$scope.message = 'Hello!!';
});
I'm going through Scotch.io's MEAN Machine book, and I'm nearly done. Problem is I can't get my Angular code to run correctly——even when I'm literally copying the code from their Github. Whenever I open my app on localhost, ngRoute fails to load (or be injected or whatever) correctly.
Here is my code:
App.js
angular.module('userApp', ['ngAnimate', 'app.routes', 'authService', 'mainCtrl', 'userCtrl', 'userService'])
]);
App.routes
angular.module('app.routes', ['ngRoute'])
.config(function($routeProvider, $locationProvider) {
$routeProvider
//home page route
.when('/', {
templateUrl : 'app/views/pages/home.html'
})
//route for the login page
.when('/login', {
templateUrl : 'app/views/pages/login.html',
controller : 'mainController',
controllerAs : 'login'
});
//get rid of the hash in the URL (url prettification)
$locationProvider.html5Mode(true);
});
mainCtrl.js
angular.module('mainCtrl', [])
.controller('mainController', function($rootScope, $location, Auth) {
var vm = this;
//get user info if logged in
vm.loggedIn = Auth.isLoggedIn();
//check to see if user is logged in ON EVERY REQUEST
$rootScope.$on('$routeChangeStart', function() {
vm.loggedIn = Auth.isLoggedIn();
//get user information on route change
Auth.getUser()
.success(function(data) {
vm.user = data;
});
});
//this function handles the login form
vm.doLogin = function() {
vm.processing = true;
//call the Auth.login() function
Auth.login(vm.loginData.userName, vm.loginData.password)
.success(function(data) {
vm.processing = false;
//if user is logged in, redirect to user page
$location.path('/users');
});
};
//function to handle logging out
vm.doLogout = function() {
Auth.logout();
//reset ALL user info
vm.user = {};
$location.path('/login');
};
});
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>User CRM</title>
<!-- FOR ANGULAR ROUTING -->
<base href="/">
<!-- CSS -->
<!-- load bootstrap from CDN and custom CSS -->
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.1/paper/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css">
<link rel="stylesheet" href="assets/css/style.css">
<!-- JS -->
<!-- load angular and angular-route via CDN -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-route.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular-animate.js"></script>
<!-- controllers -->
<script src="app/controllers/mainCtrl.js"></script>
<script src="app/controllers/userCtrl.js"></script>
<!-- services -->
<script src="app/services/authService.js"></script>
<script src="app/services/userService.js"></script>
<!-- main Angular app files -->
<script src="app/app.routes.js"></script>
<script src="app/app.js"></script>
</head>
<body ng-app="userApp" ng-controller="mainController as main">
<!-- NAVBAR -->
<header>
<div class="navbar navbar-inverse" ng-if="main.loggedIn">
<div class="container">
<div class="navbar-header">
<span class="glyphicon glyphicon-fire text-danger"></span> User CRM
</div>
<ul class="nav navbar-nav">
<li><span class="glyphicon glyphicon-user"></span> Users</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li ng-if="!main.loggedIn">Login</li>
<li ng-if="main.loggedIn" class="navbar-text">Hello {{ main.user.username }}!</li>
<li ng-if="main.loggedIn">Logout</li>
</ul>
</div>
</div>
</header>
<main class="container">
<!-- ANGULAR VIEWS -->
<div ng-view></div>
</main>
</body>
</html>
This is the exact error I'm receiving:
https://docs.angularjs.org/error/$injector/modulerr?p0=userApp&p1=Error: [$injector:nomod] http://errors.angularjs.org/1.3.8/$injector/nomod?p0=userApp
at Error (native)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:6:416
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:21:366
at a (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:21:7)
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:21:250
at https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:35:424
at s (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:7:302)
at g (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:35:202)
at Ob (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:38:435)
at d (https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js:17:350
Remove 'userCtrl' from the dependencies in the userApp module in app.js. You may have created that file, but there probably isn't any content. This should do the trick.
I ran into the same problem, the 'userService' dependency in app.js isn't loaded in the index.html file.
To fix this issue add the userService.js file in your index.html file underneath the authService.js file like so:
<!-- services -->
<script src="app/services/authService.js"></script>
<script src="app/services/userService.js"></script>
In your index.html => <body ng-app="userApp" so you need add to your mainCtrl.js look like this:
angular.module('userApp.mainCtrl', [])
You also need do the same way to userCtrl.js, authService.js, userService.js and app.routes.js.
Now in your App.js finally may look like this:
angular.module('userApp', ['ngAnimate', 'userApp.Routes', 'userApp.authService', 'userApp.mainCtrl', 'userApp.userCtrl', 'userApp.userService'])
]);
Edit
I try your code in plunker but with commenting <base href="/"> and change
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
for it work in plunker. Here (http://embed.plnkr.co/BHyE6iWDN5uXqiitaMDU/preview) you can visit it with same error in console log. It's seem due to fail load some depedencies which i left empty at some file.
Here (http://embed.plnkr.co/eD4TYgMNq4MDHQZ7p3n0/preview) another plunker that you can see the error has gone, all of depedencies success loaded. Make sure you have correct typo & not missing the depedencies.