I have created SPA with angular v1.5.6 and angular-ui-router v1.0.0alpha0; Here is my Working Plunker .
in this SPA I have 3 page : landing page i.e. "/", /Home and /About . Home page required login ; after login we save credentials in local Storage so that on refresh of page we do not lose the page. everything is working fine but now I have issue on /Home page
when I refresh the /Home page , it gives below error for the property which is defined in data attribute of .state and page do not load
angular.min.js:117 TypeError: Cannot read property 'authorizedRoles' of undefined
route is defined in below way ( only relevant code shown below)
$stateProvider
.state("home", {
url: '/home',
templateUrl: './home/home.html',
controller: 'HomeController',
requiresAuth: true,
data : { pageTitle : 'Home', authorizedRoles: [USER_ROLES.admin, USER_ROLES.editor] }
})
and using below code in *.config* which are the cause of error
$transitionsProvider.onBefore({to: function(state) { return state.requiresAuth; } },
function($transition$, $state, AuthService) {
console.log(arguments);
var from = $transition$.to().name;
console.log(from);
if(!AuthService.isAuthenticated()) {
return $state.go("login", {referral : from});
} else {
console.log('I m logged in');
var roles = $state.current.data.authorizedRoles;
if(AuthService.isAuthorized(roles)) {
console.log('Authorized');
}
}
});
note: write any credentials in that plunker when asking for login.
after page refresh $state.current goes blank ; how to handle this situtaions?
Have you tried with dev tool?
Put a breakpoint in app.js:76 and click Home, you will see that your current state is base state which does not have data property.
resolved with this help from github
var roles = $state.current.data.authorizedRoles;
will be
var roles = $transition$.to().data.authorizedRoles;
Related
So I have this very strange error: I want to check if a user is login when enter a state and redirect them back to SignIn page if they are not. So in my config I have:
.state('home', {
cache: false,
abstract: true,
url: "/home",
templateUrl: "app/home/home.html",
onEnter: function($state, MyFirebaseService) {
// check session
var userId = MyFirebaseService.LoginUserId();
if (!userId) {
$state.go('auth.signin')
};
}
})
So I type in http://localhost:8100/#/home/courses to go into courses page without login, everything work perfectly. User got redirect back to auth.signin view. But when I type in the address bar again http://localhost:8100/#/home/courses, it throw 4 errors:
TypeError: Cannot read property '#' of null
TypeError: Cannot read property 'auth-signin#auth' of null
TypeError: Cannot read property 'auth-signup#auth' of null
My signin and signup are in an abstract view call auth. Why is that and how to fix it?
I personnaly perform those actions of authenticatio ncontrol on .run( with event catcher :
.run([
'$rootScope','authService','$q',
function($rootScope, authService,q) {
$rootScope.$on('$stateChangeStart', function(event, next, current) {
// YOUR CONTROL & REDIRECT
});
}]);
If you add some authorisation role control for instance on ui-router, for instance:
.state('home', {
url: "/home",
templateUrl: "includes/pages/homePage.html",
resolve : {
authorizedRoles : function(){ return [ USER_ROLES['su'],
USER_ROLES['user'],
USER_ROLES['admin'],
USER_ROLES['skyadmin'],
USER_ROLES['skyuser'],
USER_ROLES['skysu']
] }
}
})
You can easily check into $stateChangeStart with var authorizedRoles = next.resolve.authorizedRoles(); and compare them with your user roles
I have an angular/meteor app. I have a route that's a config page and when I go there and enter my configuration and navigate back to the display route, all my configurations are saved. When I refresh the page, they're gone.
service
app.service('Config', function(){
var localEquipment = [];
this.getEquipment = function(){
return localEquipment;
}
this.setEquipment = function(equipment){
localEquipment = equipment
}
})
route
$stateProvider
.state('display', {
url: '/display',
templateUrl: 'display.ng.html',
controller: 'DisplayController',
controllerAs: 'display'
})
.state('config',{
url: '/config',
templateUrl: 'config.ng.html'
});
so i go to config and setEquipment through my Config service and navigate back to display(using a link created in my app), and my localEquipment is set. as soon as I refresh the page, it's set back to []
You aren't using AngularUI Router to its fullest potential. When you start using resolve these types of problems will go away. Bottom line is that you should be resolving Equipment in both config and display states.
I ended up using local storage with an if check to see if it had already been set.
I am using UI Router with html5Mode enabled, states are loaded from JSON.
Expected behavior after F5 or when pasting URL is, respectively, having current state reloaded or navigating to the said state, instead the initial application state is loaded.
For e.g. root/parent/child gets redirected to root/.
By the way, navigating with ui-sref works fine.
So, how can the state be retained after page reload?
In order to retain the state of page after reload app, a url represent the state should be gave. when you include ui-route module, url will be parsed and sent to corresponding state. You don't need to parse the url handly in most cases, ui-route born to do this.
Please can you post your code here? Specifically the $stateProvider.
This is an example of a correct $stateProvider and it works fine:
$stateProvider.state('main.admin', {
url: '/admin',
resolve: {},
views: {
'main-content#main': {
controller: 'AdminController as admin',
templateUrl: 'main/admin/admin.tpl.html'
}
}
});
Seems a bit hacky, but works for now.
app.run(['$location', '$state', function ($location, $state) {
function stateFromUrl () {
var path = $location.path(),
hash = $location.hash();
// do JSON states map parsing and find a corresponding to the URL state
return state;
}
if (stateFromUrl) {
$state.go(stateFromUrl);
} else {
$state.go('home'); // initial state
}
}]);
I'm trying to redirect unauthorized people when they first enter my website via a url;
eg: example.com/#/order should be redirected to example.com/#/auth, this includes when they first visit the webpage and also navigating inbetween states.
Currently I have an abstract parent state of /order and /auth which have resolves that check for authentication and redirect otherwise. I also have a watch on the $stateChangeStart event to do the same thing.
The code for when you initially load the page works correctly, it will redirect if you visit /order/restaurant without being logged in, however if I'm on the url /auth/login I can change my url to /order/resturant and it will redirect me successful but the view will not update. I will still be able to see the /order/resturant page but the resolve and page changes were hit. Why does this happen? I've attempted to use $rootScope.$apply() without success as well.
My code is as follows for the parent states:
// Authentication Urls
.state('auth', {
url: '/auth',
templateUrl: 'modules/auth/auth.html',
abstract: true
})
// Order Urls
.state('order', {
url: '/order',
templateUrl: 'modules/order/order.html',
abstract: true
})
and my code to watch the stateChange
.run(['$rootScope', '$location', 'Auth', function($rootScope, $state, Auth) {
$rootScope.$on('$stateChangeStart', function(event, toState) {
var stateName = toState.name
console.log('State start')
if (!stateName.match(/auth/) && !Auth.isLoggedIn) {
console.log('User is not visiting auth and isn\'t logged in, redirecting....')
$state.go('auth.login')
} else if (Auth.isLoggedIn && stateName.match(/auth/)) {
console.log('User is logged in and is on the auth page, redirecting....')
$state.go('order.resturant')
}
})
}])
Looking at the documentation here (http://github.com/angular-ui/ui-router/wiki#state-change-events) you should cancel the navigation by calling event.preventDefault() before performing your new transition.
I am using combination of AngularJS and Adobe CQ5.
I have implemented routing to load different views. The views are loading perfectly but the URL is not appending the #/path and it shows the base path only, e.g.
localhost:7001/cf#/content/requestpage.html#/
rather than
localhost:7001/cf#/content/requestpage.html#/checkstatus.
Due to this, when I refresh the page it loads the route path (/) template instead of loading the same view again.
I am struggling to resolve this issue. Here's my controller code:
var demoapp=angular.module('demoApp',['ngRoute','ngSanitize']);
demoapp.config(function($routeProvider,$locationProvider) {
// use the HTML5 History API
//$locationProvider.html5mode(false);
$routeProvider
.when('/', {
templateUrl: '/content/index.html?wcmmode=disabled',
controller: 'myfirstcontroller'
})
.when('/checkstatus', {
templateUrl: '/content/housetemplate.html?wcmmode=disabled',
controller: 'houseController'
})
.otherwise({
redirectTo: '/'
});
});
demoapp.controller('houseController', function($scope, $routeParams,$http)
{
//code
});
demoapp.controller('myfirstcontroller', function($scope,$http,$rootScope,$location,$compile)
{
//On Form Submit
$scope.continueForm = function(isValid){
if (isValid)
{
$location.path('/checkstatus');
}
});
});
This is not an issue with CQ5. When you open a page from Siteadmin, by default your page is loaded within contentfinder (/cf#).
Now, contentfinder already has your page URL as the hashvalue. Hence you find that the URL doesn't get updated even though your angular views work correctly.
Try accessing the same page without contentfinder. i.e.,
http://localhost:7001/content/requestpage.html
instead of
http://localhost:7001/cf#/content/requestpage.html
You should find things working as expected.