Reputation: 8101
I am trying to use the locationProvider to remove the hashtag from the url routes in angular js but it gives me error.
app.js
var eclassApp = angular.module('eclassApp',
['ngRoute', 'eclassControllers', ]
);
eclassApp.config(['$routeProvider','$locationProvider',
function ($routeProvider, $locationProvider){
$routeProvider.
when('/',{
templateUrl: '/html/student-list.html',
controller: 'StudentsListCtrl',
}).
when('/students/:studentId',{
templateUrl: '/html/student-details.html',
controller: 'StudentDetailsCtrl',
}).otherwise({
redirectTo: '/students'
});
$locationProvider.htmlMode(true);
}]
);
the error:
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.3.13/$injector/modulerr?p0=eclassApp&p1=TypeE…oogleapis.com%2Fajax%2Flibs%2Fangularjs%2F1.3.13%2Fangular.min.js%3A17%3A1)
Am I missing something?
EDIT: calling the html5Mode function with options object like this
$locationProvider.html5Mode({
enabled:true
})
i get the following error (changed to angular full to get a better explanation of the error istead of the minified version)
Error: [$location:nobase] $location in HTML5 mode requires a <base> tag to be present!
http://errors.angularjs.org/1.3.13/$location/nobase
Upvotes: 15
Views: 33433
Reputation: 19
Step1: Inject $locationProvider
in config()
function of angular root
module and set html5Mode()
to true, syntax is change on angular 1.3
version.
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
Step2: add below settings on web.config
<system.webServer>
<rewrite>
<rules>
<clear />
<rule name="AngularJS" enabled=true stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_FILENAME}" pattern"^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
Upvotes: 1
Reputation: 31
Tested on Angular 1.6.1 version:
It requires 3 steps to remove the hashtag (#) from URL.
Step 1: enable html5mode on locationProvider through Config. sample code:
app.config(function($locationProvider, $routeProvider){
$locationProvider.html5Mode(true);
$routeProvider.when('/', {templateUrl: 'partials/home.html'}).when('/info', {templateUrl: 'partials/info.html'});
});
Step 2: provide a base href
attribute in the head section of index.html
. This should be placed on top of all script and CSS tags. the href
attributes defines the relative path of your project. sample code: base href="/demo/"
. My demo application sits on root directory of Apache web server. If your application is a sub-directory, use: base href="/demo/sub-directory/"
or base href="http://localhost/demo/sub-directory/"
Step 3: If you're running this AngularJS application on Apache server (Wamp, Mamp etc): from other StackOverflow posts, you should enable url-rewrite
module. As of Apache version 2.2+, this can be achieved by using command: FallbackResource
. Sample code: create an .htaccess
file on root directory of Apache server. Add the below command and restart the server. Provide the relative path index.html
which handles the 404 error caused due angular-route functionality. This should solve refresh/accessing deep-url's and all 404 errors.
FallbackResource /demo/sub-directory/index.html
Upvotes: 0
Reputation: 4899
Try this line:
$locationProvider.hashPrefix('!').html5Mode(true);
before this line:
$routeProvider.
Upvotes: 0
Reputation: 10240
I know this is a year old but I still, to this day, haven't found one concise and full solution to this. It's all bits and pieces from several answers all over the net, so I am going to explain it here in detail and hopefully it could be the one place where other visitors can get one full answer. *I would append to the answer but this is too long to do that. So, let's get started.
First you need to download either ngRoute or angular-ui-router. I choose the latter because it already contains all that it's in ngRoute and it still has more features. So why not?
Go to your CMD and type this
npm install --save angular-ui-router
Now go to your app.js file and write your routes like this
var app = angular.module('ngCribs', ['ui.bootstrap', 'ui.router']);
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
// Application routes
$stateProvider
.state('index', {
url: '/',
templateUrl: 'views/partials/home.html'
})
.state('listings', {
url: '/listings',
templateUrl: 'views/partials/listings-list.html'
});
// For unmatched routes
$urlRouterProvider.otherwise('/');
$locationProvider.html5Mode(true);
}]);
For your next step, you need to go to your <head>
and add your base directory
<base href="/"> </base>
By now, you shouldn't have the hashtag anymore BUT, if you go to any page other than /
and reload it, you get an error and the page doesn't load. You need to tell your server how to treat your path and base directory. So to cure this dilemma, you need a server and I prefer Express, but you can use others out there. I recommend Express because at some point you will need to get involved with MEAN stacks and guess what? Other than Mongo, you are already using Angular and Node, so why not add Express to the mix?! Go to your CMD again and do this:
$ npm install express --save
Now that you have a server installed, you must create a server.js
file and put it in the base of your directory and put the following in it. *ensure your folder paths match your directory so that they're found.
var express = require('express');
var server = express();
server.use(express.static(__dirname + '/'));
server.set('views', __dirname + 'views');
server.set('js', __dirname + 'js');
server.set('css', __dirname + 'css');
server.get('/', function(req, res){
res.render('index.ejs');
});
server.all('/*', function(req, res, next) {
// Just send the index.html for other files to support HTML5Mode
res.sendFile('index.html', { root: __dirname });
});
//the port you want to use
var port = 3006;
server.listen(port, function(){
console.log('server listening on port' + port)
});
Not done yet. As soon as you try to run the server on port 3006 you will get an error. Back to CMD and type this:
npm install ejs --save
You are done, now you just need to run your server and leave it open. So from this point forward, anything you need to do in the CMD, you will need a second CMD window. (I normally have 4 running at the time. 1-server, 2-Gulp for BrowserSync, 3-MongoDB, 4-To download any dependencies I may need along the way). So go to your CMD and do this to run your server and minimize it out of the way
node server.js
Now, you are free to go to localhost:3006
and navigate as if you were in a live server that is already config for you.
Upvotes: 1
Reputation: 629
Steps to get rid of # from URL:
Inject $locationProvider in config() function of angular root module and set html5Mode() to true
angular.module( 'app', [ ] ).config(function( $locationProvider) {
$locationProvider.html5Mode(true);
});
Include base tag in head section of first loading page of application..
Upvotes: 4
Reputation: 7666
There is an extra comma in dependency array that you have. You can remove the comma as well as include base tag in your head section of the html that you have and you are good with removal of hashtags
<base href="/">
Your dependency array:
var eclassApp = angular.module('eclassApp', ['ngRoute', 'eclassControllers'] );
Upvotes: 1
Reputation: 2220
you can use the $locationProvider like this -
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
Alternatively, you can use the base tag in your index.html (I suppose this is your landing page)
<head>
<base href="/">
</head>
Removing base tag may cause some side effects in old IE browser like IE9
Upvotes: 45