I'm kind of stuck on how to route my angular app to a new controller after login. I have a simple app, that uses 'loginservice'... after logging in, it then routes to /home which has a different template from the index.html(login page).
I want to use /home as the route that displays the partial views of my flightforms controllers. What is the best way to configure my routes so that after login, /home is the default and the routes are called into that particular templates view. Seems easy but I keep getting the /login page when i click on a link which is suppose to pass the partial view into the default.html template:
var app= angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/login', {
templateUrl: 'partials/login.html',
controller: 'loginCtrl'
});
$routeProvider.when('/home', {
templateUrl: 'partials/default.html',
controller: 'defaultCtrl'
});
}]);
flightforms.config(['$routeProvider', function($routeProvider){
//sub pages
$routeProvider.when('/home', {
templateUrl: 'partials/default.html',
controller: 'defaultCtrl'
});
$routeProvider.when('/status', {
templateUrl: 'partials/subpages/home.html',
controller: 'statusCtrl'
});
$routeProvider.when('/observer-ao', {
templateUrl: 'partials/subpages/aobsrv.html',
controller: 'obsvaoCtrl'
});
$routeProvider.when('/dispatch', {
templateUrl: 'partials/subpages/disp.html',
controller: 'dispatchCtrl'
});
$routeProvider.when('/fieldmgr', {
templateUrl: 'partials/subpages/fieldopmgr.html',
controller: 'fieldmgrCtrl'
});
$routeProvider.when('/obs-backoffice', {
templateUrl: 'partials/subpages/obsbkoff.html',
controller: 'obsbkoffCtrl'
});
$routeProvider.when('/add-user', {
templateUrl: 'partials/subpages/users.html',
controller: 'userCtrl'
});
$routeProvider.otherwise({
redirectTo: '/status'
});
}]);
app.run(function($rootScope, $location, loginService) {
var routespermission=['/home']; //route that require login
$rootScope.$on('$routeChangeStart', function(){
if( routespermission.indexOf($location.path()) !=-1)
{
var connected=loginService.islogged();
connected.then(function(msg) {
if(!msg.data) $location.path('/login');
});
}
});
});
and my controllers are simple. Here's a sample of what they look like:
var flightformsControllers = angular.module('flightformsController', []);
flightforms.controller('fieldmgrCtrl', ['$scope','$http','loginService',
function($scope,loginService) {
$scope.txt='You are logged in';
$scope.logout=function(){
loginService.logout();
}
}]);
Any ideas on how to get my partials to display in the /home default.html template would be appreciated.
1) Move all the routing into the main app.config, and remove the duplicate route for /home.
2) change this line
var flightformsControllers = angular.module('flightformsController', []);
to
var flightforms = angular.module('flightforms', []);
3) change the app definition line to inject the flightforms module:
var app= angular.module('myApp', ['ngRoute', 'flightforms']);
That should get ya close.
For one of your comments, its a good idea to have an interecptor which catches any 401 un-authenticated errors from the server. This way, if a user's session expires before a route change, they will still have to login again to start a new session. Something like this in app.config should do it.
$provide.factory('logoutOn401', ['$q', '$injector', function ($q, $injector) {
return {
'responseError': function(response) {
if (response.status === 401) {
$location.path('/login')
return $q.reject();
} else {
return $q.reject(response);
}
}
};
}]);
$httpProvider.interceptors.push('logoutOn401');
Related
Actually i was new to angular js i am trying to call my factory operation into controller i dont know where i am going wrong
and my js goes here
app.factory("myFactory",function(){
var something = {};
something.getsum = function() {
$scope.service = " heloo people"
}
return something;
});
app.controller("helloController", function($scope,myFactory) {
$scope.clickme = function() {
$scope.service=myFactory.getsum();
}
});
and my html goes here
<div ng-controller="hello controller">
<button ng-click="clickme"></button>
<h2>{{service}}</h2>
</div>
and my config goes here:
$urlRouterProvider.otherwise("/index/utilise");
$stateProvider
.state('index', {
abstract: true,
url: "/index",
templateUrl: "display.html",
controller:'mainController',
controllerAs: "parentCtrl",
})
.state('index.sample', {
url: "/home",
templateUrl: "content/sample.html",
})
.state('index.utilise', {
url: "/utilise",
templateUrl: "content/utilise.html",
})
})
First issue is that to use the myFactory factory in your controller you would need to inject it into the controller via dependency injection:
app.controller("helloController", function($scope, myFactory) {
$scope.clickme = function() {
$scope.service = myFactory.getsum();
}
});
Second issue you would not use $scope in the myFactory factory method getsum(), you would simply return the value you need:
app.factory("myFactory",function(){
var something = {};
something.getsum = function() {
return " heloo people";
}
return something;
});
Third issue is ng-click was not actually execute controller function clickme as there was parenthesis () as you would with any JavaScript function. It should be ng-click="clickme()" to actually call the function on the controller:
<div ng-controller="helloController">
<button ng-click="clickme()"></button>
<h2>{{service}}</h2>
</div>
Finally, it's unclear what the structure of your application based on the ui-router configuration your provided. With ui-router you wouldn't really have the need to use ng-controller as you can specify what controller any given view should be using. I've created multiple Plunkers, one and two, demonstrating the factory functionality with and without controllers specified for child routes. This should be more than enough to demonstrating calling a controller function in different situations.
Hopefully that helps!
I'm trying to create a page form, using ui-router module. i've created states in my config file. however when opening account/trade it only shows <div ui-view></div>. Anything i'm missing?
config
var app = angular.module("KryptoApp", ["ngRoute", "ui.router", "ngCookies", "ngAnimate"]);
// app.config(['$qProvider', function ($qProvider) {
// $qProvider.errorOnUnhandledRejections(false);
// }]);
app.config(function ($stateProvider, $routeProvider) {
$routeProvider
.when("/", {
templateUrl: "/static/templates/index.html",
controller: "IndexController"
})
.when("/register", {
templateUrl: "/static/templates/register.html",
controller: "RegisterController"
})
.when("/Login", {
templateUrl: "/static/templates/login.html",
controller: "LoginController"
})
.when("/account/trade", {
templateUrl: "/static/templates/trade.html",
controller: "TradeController"
});
$stateProvider
.state('trade', {
url: '/account/trade',
templateUrl: "/static/templates/trade.html",
controller: "TradeController"
})
.state('trade.coin', {
url: 'account/trade/coin',
templateUrl: "/static/templates/trade_coin.html",
controller: "TradeController"
});
$routeProvider.otherwise('/');
});
app.config(function ($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
app.config(['$urlRouterProvider',function($urlRouterProvider){
$urlRouterProvider.otherwise('/');
}]);
/static/templates/trade.html
<div ui-view>
/static/templates/trade_coin.html
test
im not sure ngRouter and uiRouter can coexists without harms. Im might be that ngRoute catch the browser location and then dont render your view. And has you dont have ng-view directive, the ngRouter is not able to display the content.
Could you just try to migrate all your $routeProvider.when(.. stuff to $stateProver.state(.. and then stop injecting ngRoute to your application ?
As you are using ui-router you need to configure your routs as below as per ui-router documentation :
var app = angular.module("KryptoApp", ["ngRoute", "ui.router", "ngCookies", "ngAnimate"]);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
templateUrl: "/static/templates/index.html",
controller: "IndexController"
})
.state('trade', {
url: '/account/trade',
templateUrl: "/static/templates/trade.html",
controller: "TradeController"
})
.state('register', {
url: '/register',
templateUrl: "/static/templates/register.html",
controller: "RegisterController"
})
.state('login', {
url: '/login',
templateUrl: "/static/templates/login.html",
controller: "LoginController"
})
.state('trade.coin', {
url: 'account/trade/coin',
templateUrl: "/static/templates/trade_coin.html",
controller: "TradeController"
});
$urlRouterProvider.otherwise('/');
});
app.config(function ($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
I have a route provider like this
app.config(function ($routeProvider, $locationProvider){
$locationProvider.hashPrefix('');
$routeProvider
.when('/', {
templateUrl: 'login.html',
controller: 'loginCtrl'
})
.when('/home', {
resolve:{
"check":function($location, $rootScope){
if(!$rootScope.loggedIn){
$location.path('/');
}
}
},
templateUrl:'home.html',
controller: 'homeCtrl'
})
.otherwise({
redirectTo: '/'
});
});
login.html is the first page of my app.
But after login, on reloading any page that will ends up in the login.html page
I want other pages keep alive on refresh and login.html as my opening page
Reloading page will recreate $rootScope every time. So you need to store login details in any storage like localstorage.
http://blog.teamtreehouse.com/storing-data-on-the-client-with-localstorage
This link might help you. you need to store data once you successfully logged in. and get stored data and validate the use while resolving url.
scotchApp.config(function($stateProvider, $urlRouterProvider, $compileProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$compileProvider.debugInfoEnabled(false);
// route for the home page
$stateProvider
.state('home', {
url: '/home',
templateUrl : 'pages/home.html',
controller : 'mainController'
})
// route for the about page
.state('about', {
url: '/about',
templateUrl : 'pages/about.html',
controller : 'aboutController'
})
// route for the contact page
.state('contact', {
url: '/contact',
templateUrl : 'pages/contact.html',
controller : 'contactController'
});
$urlRouterProvider.otherwise('home');
});
Try something like this.
When I am running index.html its opening but on clicking the submit button in login page I need it to redirect to another page such that validation happens in the redirected page and it displays something.
Suppose the login page opens with this url
http://localhost:51499/index.html
I enter credentials and click on submit button. I need it to redirect to another url to do the validations there and throw success message. Currently on clicking submit button is redirecting to a blank page but not the next url.
My angular code:
angular.module('Project', [])
.controller('loginCtrl', ['$scope', '$http','$location', function ($scope, $http) {
$scope.login = function (emailId, password) {
var uri = 'http://localhost:64367/api/Project/ValidateLogin/' + emailId + "/" + password;
$http.get(uri).then(function (data) {
if(data)
{
$location.path("/forgotpassword");
}
else {
alert("Error!!!");
//return;
}
});
}
}])
Route config code is here:
var mainApp = angular.module('Project', [ 'ngRoute']);
// configure our routes
mainApp.config(['$routeProvider',
function ($routeProvider) {
//In the above configuration, when user is idle for 900s (does not move mouse, press any key or button etc),
$routeProvider
// route for the login page
.when('/login', {
templateUrl: '../view/login.html',
controller: 'loginCtrl'
})
.when('/forgotpassword', {
templateUrl: '../view/ForgotPassword.html',
controller: 'forgotPasswordCtrl'
})
}]);
Error message:
You need create a new JS file for validatelogin controller and configure it with appropriate view(htmlpage1) same as login configuration.
.when('/login', {
templateUrl: '../view/login.html',
controller: 'loginCtrl'
})
.when('/validatelogin, {
templateUrl: '../view/HtmlPage1.html',
controller: 'validateloginCtrl'
})
also you need write this code
$location.path("/validatelogin") instead of $location.URL('http://localhost:51499/view/HtmlPage1.html');
Here is a sample article about this : Redirect to the original requested page after login using AngularJs
I have the following config and controllers
.config(function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'page-home.html',
controller: 'homeController',
controllerAs: 'hctrl'
})
.when('/about', {
templateUrl: 'page-about.html',
controller: 'aboutController',
controllerAs: 'actrl'
})
.when('/contact', {
templateUrl: 'page-contact.html',
controller: 'contactController',
controllerAs: 'cctrl'
});
})
.controller('homeController', function(){
this.pageClass = 'page-home'
})
.controller('aboutController', function(){
this.pageClass = 'page-about'
})
.controller('contactController', function(){
this.pageClass = 'page-contact'
});
My problem comes when I use in in the index.html.
<div class="page {{pageClass}}" ng-view></div>
Since I'm not using $scope, just writing {{pageClass}} won't work. How can I get around this using the controller as syntax?
Edit
I got a couple of good answers. I also discovered an alternate way to do this if you want to name your controllerAs values with different names: hctrl, actor and ctrl (like my code above):
You could do this in the html:
<div class="page {{hctrl.pageClass || actrl.pageClass || cctrl.pageClass}}" ng-view></div>
A good approach towards this problem is by setting the pageClass as a configuration in the routes definition and then create a directive that gets these definitions to be applied as whatever you want them to be (of course within the scope where the directive is applied to).
DEMO
Javascript
Define your route configuration with data key-value object.
.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'page-home.html',
controller: 'homeController',
controllerAs: 'hctrl',
data: {
pageClass: 'page-home'
}
})
.when('/about', {
templateUrl: 'page-about.html',
controller: 'aboutController',
controllerAs: 'actrl',
data: {
pageClass: 'page-about'
}
})
.when('/contact', {
templateUrl: 'page-contact.html',
controller: 'contactController',
controllerAs: 'cctrl',
data: {
pageClass: 'page-contact'
}
});
})
Create a directive that sets these data with the directive's controller.
.directive('routeData', function() {
return {
controller: 'RouteDataController',
controllerAs: 'RouteData',
bindToController: true
}
})
.controller('RouteDataController', function($rootScope, $route) {
var self = this;
$rootScope.$on('$routeChangeSuccess', setCurrentRouteData);
setCurrentRouteData();
function setCurrentRouteData() {
angular.extend(self, $route.current.$$route.data || {});
}
})
In your index.html apply the directive itself and access the directive's controller to get the data values.
<div ng-view route-data class="page {{ RouteData.pageClass }}"></div>
Specify the controller as name
<div class="page {{hctrl.pageClass}}" ng-view></div>
Whatever you wrote in the controllerAs value need to be prepended to the variable, like {{actrl.pageClass}}