This question already has answers here:
Removing the fragment identifier from AngularJS urls (# symbol)
(14 answers)
Closed 7 years ago.
Is it possible to not to give # symbol from url to display record by giving id from url directly?
I am developing a website in which I have only one view page as Login.html.
I need to access it by giving id of user from url as abc.in/1 here 1 is id of user. I set Login.html as a default page and when I try to access it by giving abc.in/1 ,i.e. id in url it can not display the record. but when I give abc.in#/1 it displays the record properly. I dont want to access it by giving # in url.
My code is as follow-
<html ng-app="myApp" style="height: 500px; overflow: auto;">
<head>
<meta charset="utf-8">
<base href="/">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title style="color: white;">c60</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<script src="../app/js/controllers/LoginController.js"></script>
</head>
<body>
---record details
</body>
</html>
and in app.js-
angular.module('myApp', [
'ngRoute', 'ngResource', 'ngCookies',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers',
'ui.bootstrap', 'ngAnimate', 'ngDragDrop' //'ngSanitize',
]).
config(['$routeProvider','$locationProvider', function ($routeProvider,$locationProvider) {
$routeProvider.when('/:id',
{
templateUrl: '/Login.html',
controller: 'LoginController'
});
$routeProvider.otherwise({ redirectTo: '' });
//check browser support
if (window.history && window.history.pushState) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
}
}])
How to do that? I just dont want to give # in url to display a record of perticular id provided in url.I need a clean url.How to do that?
I tried to remove the # from my ulrs using the tip from the following question Removing the # symbol from angular.js urls .Now, the issue is that my url is not working if I try a direct access to them. from the given example in the related question if put the url below directly in the browser http://localhost/phones ; in my case it is abc.in/1
I'll get a 404 error. Any idea how to solve this?
It is possible to suppress the # in the url of an angular application. To do so, you need to configure the $locationProvider which you already have injected in your app config. Add the following after the $routeProvider configuration
$locationProvider.html5Mode(true);
Finally add the following to the head section of your html file
<base href="/">
A couple of things seem to be wrong here. First even when you are having only one view in your app, it is nice to have something like an index.html which will host your ng-view directive. then when you navigate to the one view of your app, that view will be loaded where you have the ng-view directive. Secondly, from your app.js, you have something as shown below
$routeProvider.when('/:id',
{
templateUrl: '/Login.html',
controller: 'LoginController'
});
$routeProvider.otherwise({ redirectTo: '' });
So this clearly says that when you enter '/' or '/1' for example in the address bar of your browser your application will fetch login.html as stated in the templateUrl. However, in your test you are entering abc.in/1 (which I do not know where it comes from)in the url address bar of your browser. when this url is checked in the route provider's routes, no match will be found. Hence you you get a 404 error. To make the matter worse your $routeProvider.otherwise is redirecting to empty string. The right thing to do is state the various routes with their respective templateUrl for your application and set otherwsise to redirect to the root of your application which in your case is still login.html or index.html if you add that now as you have only one view. Hope this helps.
Related
I tried so hard to get this work but all my tries failed. I'm trying to learn Angular routing, I started very simple: created 4 files in the same folder: index.html, page1.html, page2.html and page3.html.
this is the index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>routing</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<script src="D:\Developer Library\MyAngular\angular.min.js"></script>
<script src="D:\Developer Library\MyAngular\Scripts\angular-route.js"></script>
<body ng-app="myApp">
one
two
three
<div ng-view></div>
<script>
var app = angular.module('myApp', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/page1', { templateUrl: 'D:\Developer Library\dom\AngularRouting\page1.html' }).
when('/page2', { template: '<h1>page2.html</h1>' })//the template is working fine unlike templateUrl
.when('/page3', { template: '<h1>page3.html</h1>' });
//page1.html, page2.html, page3.html are just files holding headers with some text.-->
})
</script>
</body>
</html>
I got these errors in the console window:
XMLHttpRequest cannot load
file:///D:/Developer%20LibrarydomAngularRoutingpage1.html. Cross
origin requests are only supported for protocol schemes: http, data,
chrome, chrome-extension, https, chrome-extension-resource.
and:
Error: [$compile:tpload]
http://errors.angularjs.org/1.5.8/$compile/tpload?p0=D%3ADeveloper%20LibrarydomAngularRoutingpage1.html&p1=-1&p2=
at angular.min.js:6
at angular.min.js:156
at angular.min.js:131
at m.$eval (angular.min.js:145)
at m.$digest (angular.min.js:142)
at m.$apply (angular.min.js:146)
at HTMLBodyElement. (angular.min.js:115)
at Sf (angular.min.js:37)
at HTMLBodyElement.d (angular.min.js:37)
I made every possible change to get it work: I changed the href value of the anchor elements to /#/page1, #/page1, /page, page , I also changed the templateUrl value to similar values (my last try was the full path of the file!)
I'm actually confused between the href value and the first parameter of when method and the templateUrl, so I have some questions that I think will help me understand how routing work in angular:
What each of them refers to: are the href and the first argument of when method the same?
Can I assign the href attribute any value, and refer to it in the when argument?
Is templareUrl value related to the location of the current file(index.html),
What does the hash symbol # mean and why it's important?
Angular is loading templates via AJAX, and AJAX can not access local file system.
You must run you app on a server (you can use local server) for templateUrl to work.
I want to remove the # on angularjs url. So I followed this blog.
This is my .config() :
.config(['$stateProvider', '$locationProvider' function($stateProvider, $locationProvider,) {
$stateProvider.state('main', {
url: '/',
templateUrl: 'path/to/main.html',
controller:'mainCtrl'
})
$locationProvider.html5Mode(true);
}])
And this is my <header> :
<head>
<scripts>....
<base href="/"> // I ADDED THIS
</head>
But when I access the / link. Like this http://localhost/my-app/ it only shows a blank page. There are no error/s on the console so Im assuming that the problem is on the loading of the template. Im using ui.router. Someone encountered this problem? Thanks.
1st
When you use <base href="/"> yu set ALL relative URLs appends to that path.
So IF your app is aviable at /my-app/ use <base href="/my-app/">
Also you can try relative base href <base href="./">, but i don't recomend it.
Now your app is in http://localhost/my-app/ but base is http://localhost/
2nd
When you use html5 routing, you may ensure that webserver does not repsonse other page, but your index.html
3rd, after that check your JS, maybe cant load template because of base url...
I am currently at /addDoc, and I want current route I am at. Here is my controller:
app.controller('DocRegistrationController',[ '$http', '$scope', '$upload', '$location', function($http, $scope, $upload, $location){
$scope.validation=function(){
alert($location.path());
}
}
However it returns empty. I dont want to hardcode all the routes. What am I doing wrong?
$location service respond for parsing url in browser address bar and make the URL available to your APP.
Because you're using regular URL path and search segments, you have to set $locationProvider html5Mode to true.
$locationProvider will use hashbang as default mode.
If you don't set html5Mode to true, you will get empty string when you try to fetch url path.
Then use $location service to fetch the url path after set html5Mode.
And write your own rule to process the path.
Assume that your Full URL looks like: http://example.com/person/show/321
Main.js
angular.module("MyAPP",[],function($locationProvider){
$locationProvider.html5Mode(true);
});
function MainController($location){
var pId = $location.path().split("/")[3]||"Unknown"; //path will be /person/show/321/, and array looks like: ["","person","show","321",""]
console.log(pId);
}
index.html
<!DOCTYPE html>
<html lang="en" ng-app="MyAPP">
<head>
<meta charset="utf-8">
<title>Angular test</title>
</head>
<body ng-controller="MainController">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
<script src="js/main.js"></script>
</body>
</html>
Hope this is helpful for you.
Use $location.absUrl()....Full URL Looks like : http://localhost:6292/Example/URLName
Try also this, which is native code in JS. It worked for me. But if you need to parse long url with many nested pages, you have to modify the code a bit.
var path = "/" + window.location.pathname.split('/')[1];
console.log(path
);
I am building a web Single Page Application using AngularJS. I need that clicking on link change URI in client browser without http request.
http://example.com/ ---> it shows my single page application and clicking on a specific link I need the URL is http://example.com/about but without send http request and show hidden div.
I don't know what you precisely want to do but if you only want do one http request you can perhaps use angular ui router with something like
$stateProvider
.state('main', {
url: "/",
templateUrl: "main.html"
})
.state('about', {
url: "/about",
templateUrl: "main.html",
controller: function($scope) {
$scope.showDiv = "true";
}
})
That way you can switch state and because everything you need is already loaded, nothing gets loaded anymore. Or perhaps you can also use parameters.
But why is it so bad to have one additional request? That would be something interesting to know! :)
EDIT: The easy approach with $location
(https://docs.angularjs.org/guide/$location)
index.html:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example</title>
<base href="/">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-app="html5-mode">
<div ng-controller="LocationController">
<button ng-click="changeUrl()">Change url</button>
</div>
</body>
</html>
app.js:
angular.module('html5-mode', [])
.controller("LocationController", function ($scope, $location) {
$scope.$location = {};
$scope.changeUrl = function () {
// https://docs.angularjs.org/guide/$location
console.log("The current path: " + $location.path());
console.log("Changing url...");
$location.path('/newValue')
};
})
.config(function ($locationProvider) {
$locationProvider.html5Mode(true).hashPrefix('!');
})
Be sure to set the basePath correct.
Take a look at html2js. This is a grunt task to convert your html templates into a pre-cached js file.
Ideally you would run this as part of your build process. As well you can run a watch task to compile your HTML templates into the pre-cache whenever you save a template -- this is nice for development.
If you are already using gulp, there is a package for you. There are many alternatives to html2js that do essentially the same thing. So if it doesn't suit your needs, try another.
So with this in place, when you navigate to another page -- the HTML template will just be pulled out of angular's cache, and not grabbed from the server.
I have a form that I need to submit, if something goes wrong I would like to show an error page, I have a controller and view for this but I would like for the browser location textbox not to change to avoid the user from bookmarking the error page.
So I would have a page called /Items
the user submits and there was an error so I would like to show this page (itemsError.html) to the user but I don't want to allow the user to bookmark /ItemsError
If I plugin into the routeprovider then the browser location bar is going to update with something like /ItemsError and at a later date the user could bookmark the page, but this page is a dynamic page and should only be shown depending on the result of the form submission.
What is Angular's best practice for supporting something like this?
Thanks
config.js
$routeProvider.when('/', {
template: '/views/home.html',
});
index.html
<!doctype html>
<html lang="en" ng-controller="app">
<head>
</head>
<body>
<ng-include src="page"></ng-include>
</body>
</html>
controllers.js
controller('app', ['$scope','$route',function($scope,$route) {
$scope.$on("$routeChangeSuccess",function($currentRoute,$previousRoute){
$scope.page = $route.current.template;
});
}]).
This will handle your general routing. Now you can dynamically swap partials in your controllers based on logic. In your example, if the form doesn't successfully complete, your error callback can just change the partial on the fly:
controller('form', ['$scope','$route',function($scope,$route) {
$scope.submit = function(){
something.get().$then(
function( value ){$scope.page = '/views/successPage.html/';},
function( error ){$scope.page = '/views/errorPage.html/';}
)
}
}]).