I want to ask you for help in this code.
app.config(function ($locationProvider, $routeProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$routeProvider
.when("/", {
templateUrl: "views/home.html",
controller: "HomeController"
}).when("/login", {
templateUrl: "/views/login.html",
controller: "LoginController"
}).when("/register", {
templateUrl: "/views/register.html",
controller: "RegisterController"
}).when("/users", {
templateUrl: "/views/admin/users.html",
controller: "UserController",
requiresAuth : true
}).otherwise({
redirectTo: "/"
});
}).run(function($rootScope, Session) {
$rootScope.$on("$routeChangeStart", function(event, next, current) {
if (next.requiresAuth && !Session.getIsAdmin()) {
alert("You are not authorized");
event.preventDefault();
}
});
});
when I go to non-existent address it shows err:
Error: No default engine was specified and no extension was provided.
, so the otherwise param doesn`t work, why not?
This error comes from the server, not from angular. You need to configure your server to serve the index.html page for this "non-existent" address (and for all the existent ones too, BTW. Read Understanding what it takes to remove the hash # from angular routes).
Angular can't do anything if there is no HTML page and no application at all. Once the index.html is loaded from the server, the angular application will start, will inspect what the URL is, will detect that it doesn't match any route, and will then redirect to the home page.
Related
I would like to restrict and redirect access to certain routes in my angular app. I realize there were other questions similar to this, but because angular and firebase keep evolving, some of the earlier solutions no longer work and I would like to have the simplest possible solution as my current goal is not to make a production app, but an app that works.
I can log in and log out and every time I log in I set a rootscope variable to true and every time I log out I set that variable to false. Given this, how can I restrict my routes and redirect to the login page when the user isn't logged in?
angular
.module('angularappApp', [
'ngCookies',
'ngResource',
'ngRoute',
'ngSanitize',
'firebase'
])
.config(function ($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl',
controllerAs: 'main'
})
.when('/chat', {
templateUrl: 'views/chat.html',
controller: 'ChatCtrl'
})
.when('/login', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.when('/register', {
templateUrl: 'views/register.html',
controller: 'RegisterCtrl'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'AboutCtrl',
controllerAs: 'about'
})
.when('/logout', {
template: 'Loging out...',
controller: 'LogoutCtrl'
})
.otherwise({
redirectTo: '/'
});
}).constant('FBURL', 'https://dazzling-inferno-7746.firebaseio.com/');
This is my app.js file.
The most common way to implement such a feature in your app is watching page changes and cancel transition if condition is failed.
In your example you can watch route changes and check if $rootScope has specific attribute true or false.
$rootScope.$on('$locationChangeStart', function(event, next, current) {
// check if user is login if not then prevent default action
// and redirect user to login page
if(!$rootScope.isLogin){
event.preventDefault();
$location.path('login');
}
});
and I suggest that you should put this code block in a run block or at least config block as they are first things to start work in angularjs applications...
and strongly suggest you to use ui.router over default routing as it has much more features then default ones...
restrict specific page
if you want to restrict a specific page you can add a custom attribute on its defination and check if it is pass all condition then give it a go...
.when('/chat', {
templateUrl: 'views/chat.html',
controller: 'ChatCtrl',
// add a custom property for checking at route changes
requireLogin: true
})
then in your event block check it like that
$rootScope.$on('$locationChangeStart', function(event, next, current) {
// get next route
var nextRoute = $route.routes[$location.path()];
// check if next page requires login then
// check if user is login if not then prevent default action
// and redirect user to login page
if(nextRoute.requireLogin && !$rootScope.isLogin){
event.preventDefault();
$location.path('login');
}
});
When user go to either localhost:8888 or localhost:8888/, my angular application change to url to http://localhost:8888/#!/
This is my angular app in home page:
app.config(['$locationProvider', '$routeProvider',
function($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
$routeProvider
.when('/', {
redirectTo: ((window.status === 'signup') ? '/signup' : '/signin')
})
.when("/signin", {
templateUrl: "/public/user/signin.html",
controller: "signinController"
})
.when('/signup', {
templateUrl: "/public/user/signup.html",
controller: "signupController"
})
.otherwise({
redirectTo: '/'
});
}
])
if user go to http://localhost:8888/auth, angular redirects to http://localhost:8888/auth#!/signin,
only if user go to http://localhost:8888/auth/, angular redirects to http://localhost:8888/auth/#!/signin
app.config(['$locationProvider', '$routeProvider',
function($locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
$routeProvider
.when('/', {
redirectTo: ((window.status === 'signup') ? '/signup' : '/signin')
})
.when("/signin", {
templateUrl: "/public/user/signin.html",
controller: "signinController"
})
.when('/signup', {
templateUrl: "/public/user/signup.html",
controller: "signupController"
})
.otherwise({
redirectTo: '/'
});
}
])
the angular official website and most of the books recommend using xxx/#!/xxx format. How can I do that?
Edit: I understand that I can add the trailing slash from the server side. but user can directly type xxx.com/auth.
Why is xxx.com working but not xxx.com/auth?
Edit2: the tutorial sample project works for all urls. we have pretty much the same implementation
http://angular.github.io/angular-phonecat/step-8/app/#/phones
try to enter http://angular.github.io/angular-phonecat/step-8/app (without the trailing slash
Tutorial link: https://docs.angularjs.org/tutorial/step_07
This is something you should fix on your back-end by adding a 301 redirect from /auth to /auth/.
Nginx:
rewrite ^/auth$ /auth/ permanent;
Apache:
Redirect "/auth" "/auth/" [R=301]
I'm trying to make a routing , it's working when I just clicking on links , but when I refresh the page , browser says not found ! I'm using html5mode , also when I set the # on url and search page manually it just works! what's the problem ?
this is app.js :
app = angular.module("app", [ "ngRoute" ]);
app.config(function($locationProvider, $routeProvider) {
$routeProvider.when("/", {
templateUrl: "partials/index.html",
controller: "mainCtrl"
}).when("/index", {
templateUrl: "partials/index.html"
}).when("/person", {
templateUrl: "partials/person.html",
controller: "personCtrl"
}).when("/person/:id", {
templateUrl: "partials/personShow.html",
controller: "personShowCtrl"
}).when("/about", {
templateUrl: "/partials/about.html"
}).when("/contact", {
templateUrl: "/partials/contact.html"
}).when("/coworking", {
templateUrl: "/partials/coworking.html"
}).otherwise({
redirectTo: "/partials/person.html"
});
$locationProvider.html5Mode(true);
});
Here is excatly same question, anwsered by me:
tl;dr
You need a webserver, like Apache, Nginx or something based on Node.js and you need to redirect all your http calls to index.html
I'm a newbie with AngularJS and I got a problem that I think that's it's can be configurable in my routeProvider.
I have this route
angular
.module('app', ['ngRoute', 'ngStorage'])
.config(['$routeProvider', function ($routeProvider) {
debugger;
$routeProvider.when('/:module/:task/:id/:menu/:action', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/:module/:task/:id/:menu', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/:module/:task/:id', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/:module/:task', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/:module', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/', { templateUrl: 'app/start.html' });
$routeProvider.otherwise({ redirectTo: '/' });
}
]);
the problem: When I just type http://localhost:53379 I'm redirected to http://localhost:53379/#/ . Where come from the /#/ ?
By default, AngularJS will route URLs with a hashtag.
For example:
http://domain.com/#/home
http://domain.com/#/about
You can very easy remove the hashtag from the URL by setting html5Mode to true in your config:
$locationProvider.html5Mode(true);
so in your code it will be:
angular
.module('app', ['ngRoute', 'ngStorage'])
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
debugger;
$routeProvider.when('/:module/:task/:id/:menu/:action', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/:module/:task/:id/:menu', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/:module/:task/:id', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/:module/:task', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/:module', { templateUrl: 'app/blank.html', controller: PagesCtrl });
$routeProvider.when('/', { templateUrl: 'app/start.html' });
$routeProvider.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode(true);
}
]);
Just after that you have to make sure that your backed will redirect all requests to your home page if you are doing "Single Page App"
Angular adds it by default. I don't know it this is the main reason, but one reason is that the routing doesn't work in older versions of IE. I had this problem in one angularjs app that didn't work in IE9 because of this reason.
Anyways, to remove the hashtag simply add $locationProvider.html5Mode(true); after your routing-declarations.
You can read more about it here: http://scotch.io/quick-tips/js/angular/pretty-urls-in-angularjs-removing-the-hashtag
This /#/ is used to create a single page application. the # is used to prevent that the page is completely reloaded. Angular then catches the new URL and loads the correct controller and partials depending on your route configuration.
Since HTML5 it is possible to remove this behavior with $location.html5Mode(true).
Source:
AngularJS documentation
FOr my angular application , I want to use $locationProvider.html5Mode(true) to remove '#' sign from URL.
I also used but it is not working.
My index.html include "" in header section.
My app.js is as follows.
$routeProvider
.when('/signIn', {
controller: 'signInController',
templateUrl: 'html/views/sign-in.html'
})
.when('/login', {
controller: 'LoginController',
templateUrl: 'html/views/log-in.html'
})
.otherwise({ redirectTo: '/login' });
$locationProvider.html5Mode(true);
All my code (html and scripts) is under App directory. But when I am trying to run my login page is not getting loaded.