Put the case I've got a route like
.config(function (CONFIG,$routeProvider) {
$routeProvider
.when('/', {
templateUrl: CONFIG.site.path_views + '/index/index.html',
controller: 'IndexCtrl'
})
.when('/contestant/create', {
templateUrl: CONFIG.site.path_views + '/contestant/create.html',
controller: 'ContestantCreateCtrl'
})
.when('/contestant/thanks', {
templateUrl: CONFIG.site.path_views + '/contestant/thanks.html',
controller: 'ContestantThanksCtrl'
})
.when('/product', {
templateUrl: CONFIG.site.path_views + '/product/index.html',
controller: 'ProductCtrl'
})
.when('/prize', {
templateUrl: CONFIG.site.path_views + '/prize/index.html',
controller: 'PrizeCtrl'
})
.otherwise({
redirectTo: '/'
});
})
I'd like to deny access or simply redirect the user
to /contestant/create if he/she has filled in the form
but I don't find a way :(
app.run( function(VisitedRoutes) {
VisitedRoutes.init();
};
app.factory('VisitedRoutes', function($rootScope,$location) {
var routes = [];
return {
add : function(){
routes.push($location.path());
},
all:function(){
return _.uniq(routes);
},
hasRoute:function(value){
return _.indexOf(this.all(), value)
},
init:function(){
var that = this;
$rootScope.$on('$routeChangeSuccess', function (scope, next, current) {
that.add();
});
}
}
});
app.controller('ContestantCreateCtrl',function($scope,$location,VisitedRoutes) {
if(VisitedRoutes.hasRoute('/contestant/thanks') !== -1){
$location.path('/');
}
});
credit to #Jesus Rodriguez :)
Related
I am trying to restrict access to some pages within the public directory using Angular routing.
.when('/adminprofile', {
templateUrl: '../partials/adminprofile.html',
access: {restricted: true}
})
I am trying to read what I believe is a property called access which I declared, called access
myApp.run(function ($rootScope, $location, $route, AuthService) {
$rootScope.$on('$routeChangeStart',
function (event, next, current) {
AuthService.getUserStatus()
.then(function(){
if (next.access.restricted && !AuthService.isLoggedIn()){
$location.path('/login');
$route.reload();
}
});
});
});
But what I get is this error:
TypeError: next.access is undefined
How can I read the property or how can i achieve this in a better way?, Thanks
EDIT :
According to suggestion, I have changed the code and it looks as it follows:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: '../partials/home.html',
resolve: {
access: false
}
})
.when('/home', {
templateUrl: '../partials/home.html',
resolve: {
access: false
}
})
.when('/login', {
templateUrl: '../partials/login.html',
controller: 'loginController',
resolve: {
access: false
}
})
.when('/logout', {
controller: 'logoutController',
resolve: {
access: false
}
})
.when('/register', {
templateUrl: '../partials/register.html',
controller: 'registerController',
resolve: {
access: false
}
})
.when('/adminprofile', {
templateUrl: '../partials/adminprofile.html',
resolve: {
access: true
}
})
.otherwise({
redirectTo: '/'
});
});
And I have my run function:
myApp.run(function ($rootScope, $location, $route, AuthService) {
debugger;
$rootScope.$on('$routeChangeStart',
function (event, next, current) {
AuthService.getUserStatus()
.then(function(){
if (next.resolve.access && !AuthService.isLoggedIn()){
$location.path('/login');
$route.reload();
} else{
$location.path($route.current.originalPath);
}
});
});
});
Now I can see the value of access:
next.resolve.access
but is not displaying anything, I run in debug and can see that actually is going through the $routeChangeStart callback , whyyyyy?? helppppp!
ok fellas, is done, this is the right way to do it:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: '../partials/home.html',
resolve: {
access: function() {
return false;
}
}
})
.when('/home', {
templateUrl: '../partials/home.html',
resolve: {
access: function() {
return false;
}
}
})
.when('/login', {
templateUrl: '../partials/login.html',
controller: 'loginController',
resolve: {
access: function() {
return false;
}
}
})
.when('/logout', {
controller: 'logoutController',
resolve: {
access: function() {
return false;
}
}
})
.when('/register', {
templateUrl: '../partials/register.html',
controller: 'registerController',
resolve: {
access: function() {
return false;
}
}
})
.when('/adminprofile', {
templateUrl: '../partials/adminprofile.html',
resolve: {
access: function() {
return true;
}
}
})
.otherwise({
redirectTo: '/'
});
});
myApp.run(function ($rootScope, $location, $route, AuthService) {
debugger;
$rootScope.$on('$routeChangeStart',
function (event, next, current) {
AuthService.getUserStatus()
.then(function(){
if (next.resolve.access && !AuthService.isLoggedIn()){
$location.path('/login');
$route.reload();
}
});
});
});
resolve has to be a function
Resolve will open your route with a resolved variable (that can be injected into controller) as soon as it gets value (instantly or when returned promise will be resolved)
as it was not returning a value, the router seems to be stuck waiting for a value to resolve.
So, I have a state where the resolve spits out an array which shows correctly on the frontend.
But I can't seem to be able to pass the parent resolve data to the child state.
$stateProvider.state('berliner', {
url: '/berlinerliste',
params : {search: 'Berliner 2017'},
resolve: {
fair: function(SearchService, $stateParams) {
return SearchService.getAllExhibitors($stateParams.search);
}
},
views: {
'header': {
templateUrl: 'header.htm'
},
'main':{
templateUrl: 'bl2017.htm',
controller: function($scope, fair){
$scope.fair = fair;
console.log($scope.fair);
}
}
}
})
.state('berliner.exhibitor', {
url: '/{id}',
resolve: {
exhibitor: function($stateParams, fair) {
var slug = $stateParams.id;
return slug;
}
},
views: {
'header': {
templateUrl: 'header.htm'
},
'wop':{
templateUrl: 'exhibitor.htm',
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
}
}
})
All the console log come out undefined.
What am I missing?
PLUNKR
Here's a Plunkr to examplify the issue.
I would say, that the concept should work.. just:
controller belongs to view. not to all views: {}
E.g. this (wrong)
// each view can have controller,
// but views : {} property 'controller' is not used at all
views: {
'header': {
templateUrl: 'header.htm'
},
'wop':{
templateUrl: 'exhibitor.htm',
},
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
should be adjusted as that:
views: {
'header': {
templateUrl: 'header.htm'
controller: function($scope, exhibitor, $filter){
$scope.fairs = $scope.fair;
console.log($scope.fair);
$scope.chosenexhibitor = $filter("filter")($scope.fairs, {'slug':exhibitor}, true);
console.log($scope.chosenexhibitor);
}
},
'wop':{
templateUrl: 'exhibitor.htm',
controller: ...
There is an example, how
parent does resolve
child view's controller consumes it
states:
.state('parent', {
url: "/parent",
templateUrl: 'tpl.html',
resolve: {
example: ['$timeout', function($timeout){
return $timeout(function(){
return {x: 1}
},100)
}],
},
})
.state('parent.child', {
url: "/child",
templateUrl: 'tpl.html',
controller: 'ChildCtrl',
})
child controller
.controller('ChildCtrl', ['$scope', 'example', function ($scope, example) {
console.log(JSON.stringify(example));
}])
Check it here
In my main module i have used ui-bootstrap modal for checking login authentication.From run block i have called to loginModal service but it is giving Error
TypeError: loginModal is not a function
angular.module('myApp', ['ui.router', 'ui.bootstrap', 'loginServices','leaveServices']). config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider.
state('home', {
url:'/home',
data: {
requireLogin: false
},
views: {
'': {
templateUrl: 'partials/templates/assets/home.html'
}
}
}).
state('home.about', {
url: '/about',
templateUrl: 'partials/templates/assets/about.html'
}).
state('home.contact', {
url: '/contact',
templateUrl: 'partials/templates/assets/contactUs.html'
}).
state('/login', {
url: '/login',
data: {
requireLogin: false
},
templateUrl: 'partials/login.html',
controller: loginUserController
}).
state('/register', {
url:'/register',
data: {
requireLogin: false
},
templateUrl: 'partials/registerUser.html',
controller: registerController
}).
state('/getAllUsers', {
url: '/getAllUsers',
data: {
requireLogin: false
},
templateUrl: 'partials/getAllUsers.html',
controller: getUsersController
}).
state('/updateUser', {
url : '/updateUser/:id/:name',
data: {
requireLogin: true
},
params: {'id':null, 'name':null},
templateUrl: 'partials/updateUser.html',
controller: updateUserController
}).
state('/userLeave', {
url : '/userLeave:name',
data: {
requireLogin: true
},
params: {'name': null},
templateUrl: 'partials/userLeave.html',
controller: userLeaveController
}).
state('/leaveRequest', {
url : '/leaveRequest',
data: {
requireLogin: true
},
templateUrl: 'partials/leaveRequest.html'
});
}])
.run(function ($rootScope, $state, loginModal) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
var requireLogin = toState.data.requireLogin;
console.log('going to state '+toState.name);
if (requireLogin && typeof $rootScope.currentUser === 'undefined') {
event.preventDefault();
loginModal().then(function () {
return $state.go(toState.name, toParams);
})
.catch(function () {
return $state.go('/login');
});
}
});
})
.factory('loginModal', function ($modal, $rootScope) {
function assignCurrentUser (user) {
$rootScope.currentUser = user;
return user;
}
return function() {
var instance = $modal.open({
templateUrl: 'partials/login.html',
controller: loginUserController
});
return instance.result.then(assignCurrentUser);
}
});
here login controller
loginUserController.$inject = ['$scope','$http', 'loginFactory', '$location', '$state'];
function loginUserController($scope,$http,loginFactory,$location, $state){
$scope.validateLogin = function(name,password){
$http.get("http://localhost:3010/validateLogin?userName="+name+"&password="+password)
.then(function(response) {
if(response.data.length != 0) {
console.log("logged user data is "+JSON.stringify(response.data));
$state.transitionTo('/userLeave', {name: name});
// $scope.$close(response);
}
else
$scope.inValidUser = 'Invalid User';
});
};
$scope.cancel = $scope.$dismiss;
}
Could be because you're using an Angular service which expects a constructor which in turn, should not be returning something.
Try changing to a factory, eg
.factory('loginModal', ...
I have an Angular app that I had to update to 1.5.9 recently.
In my app it's necessary for someone to get an URL (eg.: http://somedomain/#/dashboard/1) and have a direct access to that screen, which is quite common.
In the latest version this worked perfectly, but now with 1.5.9 angular always redirects this request to the root path (http://somedomain/#/), causing all links to be broken.
How do I fix this? Is this some new rule, or a bug with this version, or some configuration I have to change?
--- UPDATE ---
My router code is a little confusing because I have several modules, and each one defines an object like this:
portal._routes = {
'/': {
controller: 'HomeController',
controllerUrl: 'portal/layout/controller/home',
templateUrl: 'app/portal/layout/template/home.html'
},
'/application': {
controller: 'HomeController',
controllerUrl: 'portal/layout/controller/home',
templateUrl: 'app/portal/layout/template/home.html'
},
'/dashboard': {
controller: 'DashboardListController',
controllerUrl: 'portal/dashboard/controller/dashboard-list',
templateUrl: 'app/portal/dashboard/template/dashboard-list.html'
},
'/dashboard/new': {
controller: 'DashboardFormController',
controllerUrl: 'portal/dashboard/controller/dashboard-form',
templateUrl: 'app/portal/dashboard/template/dashboard-form.html'
},
'/dashboard/:id': {
controller: 'DashboardViewController',
controllerUrl: 'portal/dashboard/controller/dashboard-view',
templateUrl: 'app/portal/dashboard/template/dashboard-view.html'
},
'/dashboard/public/:id': {
controller: 'PublicDashboardViewController',
controllerUrl: 'portal/dashboard/controller/dashboard-view-public',
templateUrl: 'app/portal/dashboard/template/dashboard-view-public.html'
},
'/dashboard/:id/edit': {
controller: 'DashboardFormController',
controllerUrl: 'portal/dashboard/controller/dashboard-form',
templateUrl: 'app/portal/dashboard/template/dashboard-form.html'
},
'/user/form': {
controller: 'UserFormController',
controllerUrl: 'portal/user/controller/user-form',
templateUrl: 'app/portal/user/template/user-form.html'
},
'/user/new': {
controller: 'UserFormController',
controllerUrl: 'portal/user/controller/user-form',
templateUrl: 'app/portal/user/template/user-form.html'
}
};
Then I have this in the main angular module file:
connecta.config(function ($controllerProvider, $compileProvider, $provide, $filterProvider, $translateProvider, $routeProvider, $httpProvider, $sceProvider, applications) {
configureLazyProviders($controllerProvider, $compileProvider, $provide, $filterProvider);
configureTranslations($translateProvider, window.navigator);
configureRoutes($routeProvider);
configureRequestInterceptors($httpProvider, applications);
configureHTTPWhitelist($compileProvider, $sceProvider);
configureAuthenticationListener($httpProvider, $routeProvider);
});
Which calls this configureRoutes function:
function configureRoutes($routeProvider) {
var allRoutes = buildRoutes(portal, presenter, maps);
angular.forEach(allRoutes, function (route, url) {
if (route.controllerUrl) {
if (!route.resolve) {
route.resolve = {};
}
if (!route.resolve.load) {
route.resolve.load = function ($q, $rootScope) {
var deferred = $q.defer();
require([route.controllerUrl], function () {
deferred.resolve();
$rootScope.$apply();
});
return deferred.promise;
};
}
}
$routeProvider.when(url, route);
});
$routeProvider.otherwise({
template: '<h1>Not Found</h1>'
});
}
Which calls this auxiliary buildRoutes function:
function buildRoutes() {
var finalRouteObject = {};
angular.forEach(arguments, function (module) {
// Coloca a referĂȘncia
angular.forEach(module._routes, function (value) {
value.module = module.name;
});
$.extend(true, finalRouteObject, module._routes);
});
return finalRouteObject;
}
This code was working and has not been changed recently, only Angular has been updated and it does this weird redirect to the root path.
I have tried several method but $state.go() is not refreshing my page.Here is my controller. All process works but i cannot reload the browse page using $state.go() function.
angular.module('kawaadi.controllers', [])
.controller('AppCtrl', function ($scope, Service, $ionicLoading, $ionicModal, $ionicPopup, $timeout, $state, $http,$location) {
$scope.loginData = {};
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope
}).then(function (modal) {
$scope.modal = modal;
});
$scope.closeLogin = function () {
$scope.modal.hide();
};
$scope.login = function () {
$scope.modal.show();
};
$scope.logout = function () {
localStorage.setItem("token", "");
$state.go('login');
};
$scope.statusData = function (pid, uid, status) {
$ionicLoading.show({
template: 'Processing...'
});
Service.change_status(pid, uid, status, $http).success(function (data) {
if (data.status === 'success' && data.notification_status === 'success') {
$ionicLoading.hide();
var alertPopup = $ionicPopup.alert({
title: 'Success!',
template: 'Successfully changed and notification has been send!'
});
} else if (data.status === 'success' && data.notification_status === 'failure') {
$ionicLoading.hide();
var alertPopup = $ionicPopup.alert({
title: 'Success!',
template: 'Successfully changed but failed to send notification!!'
});
}
alertPopup.then(function (res) {
if (res == true) {
$state.go('app.browse');
}
});
}).error(function (data) {
var alertPopup = $ionicPopup.alert({
title: 'Process failed!',
template: 'Some thing went wrong!'
});
});
}
})
and here is my url router
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'templates/auth.html',
controller: 'LoginCtrl'
})
.state('app', {
url: '/app',
templateUrl: 'templates/menu.html',
controller: 'AppCtrl'
})
.state('app.search', {
url: '/search',
views: {
'menuContent': {
templateUrl: 'templates/search.html'
}
}
})
.state('app.browse', {
url: '/browse',
views: {
'menuContent': {
templateUrl: 'templates/browse.html',
controller: 'pickupCtrl'
}
}
})
.state('app.playlists', {
url: '/playlists',
views: {
'menuContent': {
templateUrl: 'templates/playlists.html',
controller: 'PlaylistsCtrl'
}
}
})
.state('app.single', {
url: '/playlists/:playlistId',
views: {
'menuContent': {
templateUrl: 'templates/playlist.html',
controller: 'PlaylistCtrl'
}
}
});
});
Please guide me. Thanks in advance
Please modify all your states as
.state('emailConfirmation',{
cache: false,
url:"/emailConfirmation",
templateUrl:"app/session/emailConfirmation.html",
controller: 'EmailConfirmationCtrl'
})
and to reload the current page please use these command
$state.transitionTo($state.current, $stateParams, {
reload: true,
inherit: false,
notify: true
});
If you want to force reload the current state, then you probably need to use $state.go($state.current.name, $state.params, {reload: true}) as mentioned here
Just Add the following in Your ion-view tag
<ion-view cache-view="false">