I would like after getting credentials from another website, to change the url in my angularJS application.
I am setting my app like this
angular.module('demoApp', [])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/example', {
templateUrl: 'views/example.html',
controller: 'ExampleCtrl'
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
})
In my MainCtrl controller I change url like this :
$location.url($location.path()); // to remove url query params
$location.path('/example'); // to change the url
But this cause Cannot GET /example when I refresh the page.
Is there a solution for this ?
Thanks for your help.
It seams you didn"t handle URL rewriting needed when you activate the HTML5 mode (actually, the /example url doesn't exists, right now the only angular existing url is index.html)
So you'll have to handle URL rewriting server side.. For example for apache in a .htaccess file :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule !\.\w+$ index.html [L]
</IfModule>
Or if you're using grunt-connect :
connect: {
dev: {
options: {
port: 9002,
hostname: '*',
middleware: function(connect) {
return [
//modRewrite is used to handle properly angularjs' html5 mode
modRewrite(['^[^\\.]*$ /index.html [L]']),
lrSnippet,
folderMount(connect, '/app')
];
}
}
}
}
One more thing, be carefull, you're doing a double location change. If you want to remove query params, I sugest you to do this :
$location.path(url);
// clear any query params
$location.$$search = {};
$location.$$compose();
Related
I cannot route directly by using input in browser.
I am using $locationProvider.html5Mode(true);
so when i write the url in browser then they cannot route in angular js.
AppRouting.js
myApp.config(['$routeProvider',
function($routeProvider) {
$locationProvider.html5Mode(true);
$routeProvider.
when('/', {
templateUrl: 'home.html',
controller: 'HomeController'
})
.when('/login', {
templateUrl: 'login.html'
})
.otherwise({
redirectTo: '/phones'
});
}]);
so what can i do???
Your web server must be able to redirect your URL for it to work.
Say you are on "http://site" and you have a link leading to "http://site/foo/bar".
When you click on this link, you don't really go on this URL but rather on "http://site/index.html#/foo/bar", angularjs handles the rest.
However, if you directly access "http://site/foo/bar", your web server will try to find a path "/foo/bar" on your server, which does not exist, so you have to configure your server to redirect everything to "index.html".
As you're using Apache, you can use to add this in your .htaccess:
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
More info here.
Can someone help me understand how I can redirect an Angular state to a new URL with the query string parameters same as old ones?
Example
If my Angular application is on http://example.com, then all the requests to http://example.com/dashboard?id=123&view=test should be redirected to http://test.com/dashboard?id=123&view=test.
How should I define my state using the following code?
.state('dashboard', {
url: 'domain.com/dashboard',
controller: 'DashboardCtrl'
})
I know few tricks to transfer the state to controller and then handle it from there. But I'm wondering if there's a way to redirect it through the router only to avoid repetitive code in different controllers?
A. Angular 1
1. main.route.js:
.state('stateName', {
url: 'dashboard',
controller: ['$location', '$window', function ($location, $window) {
var url = 'domainB.com';
url += $location.$$url;
$window.location.href = url;
}]
})
B. Angular2/4
1. app.module.ts: Declare a custom provider like:
#NgModule({
providers: [
{
provide: 'externalUrlResolver',
useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {
window.location.href = `${route.data.externalUrl}${state.url}`;
}
}
]
})
2. app-routing.module.ts: Now using the custom provider we can redirect externally.
const APP_ROUTES: Routes = [
{ path: 'dashboard', component: AnyComponent,
pathMatch: 'prefix',
resolve: { url: 'externalUrlResolver' },
data: { externalUrl: 'domainB.com'}
}
]
Input
http://domainA.com/dashboard?view=list&id=123&visible=yes
This will be redirected to:
http://domainB.com/dashboard?view=list&id=123&visible=yes
I think the best solution for this is not in Angular -- which runs in the browser after the code has already been loaded -- but on the server. If you're using Apache, add an .htaccess rule that will redirect all requests for example.com to test.com.
Create a file named .htaccess and place it in the application root directory:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
RewriteRule ^(.*)$ http://test.com/$1 [R=302,L]
If you want the redirect to be permanent (meaning browsers and search engines will remember and won't bother going to the old domain), change 302 to 301
If this isn't a solution, you could use a CanActivateChild guard to indicate code that should be run before a route loads. Add it to the routing configuration for your base route and this code will always run before components etc... are initialized. Within it, you can read the current route and redirect the user with standard JavaScript to the new domain.
I am using angular for my app
I wanted to remove the # from the url so i added the below lines as suggested in SO answer
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
In the index.html I also added the below code as suggested here
<head>
<base href="/">
</head>
It all works fine when I navigate to pages from the home, but when i copy the url and open it in new tab, it throws 404 error
Example
When I launch the app, it's opening http://localhost:portno/home.
When I refresh the page, I'm getting a 404 error.
What other configuration should i make?
My code structure is as below
.state('tab.home', {
url: '/home',
views: {
'tab-home': {
templateUrl: 'templates/tab-home.html',
controller: 'templeHome'
}
}
})
.state('tab.list', {
url: '/list',
views: {
'tab-home': {
templateUrl: 'templates/list.html',
controller: 'templeList'
}
}
})
You need to add a route on your server that will redirect you to the entrypoint of your front (i.e: index.html).
For example, if you were redirected from your home to http://localhost:portno/foo/bar, you'll need a route to match the /foo/bar one that will redirect you to your index.html.
It migth look like this (note that this is an example code of my own written for Hapi):
server.route([
{
method: 'GET',
path: '/foo/bar',
handler: function(request, reply) {
reply.file('./public/index.html');
}
}
...
My English is not very good, but i try to explain my self clear. I'm trying to optimize Website based on pure Angular to SEO.
Here is the link http://www.sanjosejumpstart.com/tests/project/
When you come first time to the website and start clicking on the links, routing is working fine, but when refreshing the page, i get error with
Not Found
The requested URL /tests/project/automotive was not found on this server.
Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
i can't understand why this happens.(may be because a hash is disappeared?)
Some body have any idea how i can fix that?
BASE tag on index html looks
<base href="http://www.sanjosejumpstart.com/tests/project/">
and route config look likes:
.config(['$httpProvider', '$stateProvider', '$urlRouterProvider', '$locationProvider',
function($httpProvider, $stateProvider, $urlRouterProvider, $locationProvider) {
$httpProvider.defaults.transformRequest.push(LockJS.postConvert);
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
$httpProvider.interceptors.push('Interseptor');
/* activating html5 mode */
$locationProvider.hashPrefix('!');
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
views: {
'': {
templateUrl: 'templates/main-page-content.html'
},
'article#home': {
templateUrl: 'templates/main-page/app-main-article.html',
controller: 'MainArticleCtrl'
},
'services#home': {
templateUrl: 'templates/main-page/app-main-services-list.html',
controller: 'MainServicesCtrl'
},
'services-info#home': {
templateUrl: 'templates/main-page/app-services-info.html',
controller: 'MainServicesInfoCtrl'
},
'aside#home': {
templateUrl: 'templates/main-page/app-aside-content.html'
},
'middle-slider#home': {
templateUrl: 'templates/main-page/app-middle-slider.html'
},
'map#home': {
templateUrl: 'templates/main-page/app-map.html'
}
}
})
.state('automotive', {
url: '/automotive',
views: {
'': {
template: '<h1>automotive view</h1>'
}
}
})
}])
And then comes more states.
Thank you for any advice.
You need to set up your server to return your index.html page for all requests that are not:
an API call (have these all start with /api to make this easier)
a static file request (have these all start with /pub or similar)
Then the index.html will load, Angular will bootstrap your app, which will involve examining the route and loading the correct page.
Why should I use /api or /pub?
The exact prefix is not super important (though it should make sense). What is helpful is that by using a common prefix for all API endpoints (e.g. routes you call using the $http or $resource services), you will not overlap with any client-side routes in your app.
For example, if you didn't follow this rule, say you had the following server side route configured:
/products - gets a list of products as JSON
Then you had a client-side route set up as: /products, it becomes a bit confusing as to which one you meant when you type in www.myserver.com/products.
Technically, if the server is configured correctly it could tell the difference between an AJAX request to /products asking for JSON and a "normal" HTTP GET request to /products. But it is still not ideal, because you can't tell from the URL alone which one you meant. You have to look at how it was called as well.
Alternative: Give up on HTML5 mode
If you can't configure the server like I said above, you will need to disable HTML5Mode. That way, all the relative URLs will be after the #, so the only file request the web server ever gets is for the default page for /test/project.
i found the solution, you can see all redirects now:
http://www.sanjosejumpstart.com/tests/project/home
here is the solution:
Apache server
1) index must be php, not html - index.php
2) adding BASE tag in head of the file like this = <base href="/tests/project/">
3) in app config - $locationProvider.html5Mode(true)
no need to add $locationProvider.hashPrefix('!');
and finally .htaccess
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /Locksmith-Project/project/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php/#/$1
</IfModule>
Hope it is be helpful to someone
Code bellow is from AngularJs tutorials and little bit modified by me. I wish to remove hash from url. I actually succeed, but now I have other problem.
When I use link localhost, it works just fine and redirect me to localhost/phones. But in case, that I try with direct link localhost/phones, browser throws me 404 error. Why is that so?
Code:
var phonecatApp = angular.module('phonecatApp', [
'ngRoute',
'phonecatControllers'
]);
phonecatApp.config(['$routeProvider', '$locationProvider' ,function($routeProvider, $locationProvider) {
$routeProvider
.when('/phones', {
templateUrl : 'partials/phone-list.html',
controller : 'PhoneListCtrl'
}).
when('/phones/:phoneId', {
templateUrl : 'partials/phone-detail.html',
controller : 'PhoneDetailCtrl'
}).
otherwise({
redirectTo : '/phones'
});
$locationProvider.html5Mode(true).hashPrefix('!');
}])
You have to handle url rewriting server-side for that.
Depending on your server, you'll have to add:
In apache (.htaccess for example) :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule !\.\w+$ index.html [L]
</IfModule>
If you're using grunt and grunt-contrib-connect, just add a middleware (modRewrite) with this regexp :
connect: {
options: {
port: 9002,
hostname: 'localhost' // put here any ip if you want external access
},
dev: {
options: {
middleware: function(connect) {
return [
//modRewrite is used to handle properly angularjs' html5 mode
modRewrite([
'^[^\\.]*$ /index.html [L]'
])
]
}
}
}
}
ps: that your main entry point must be index.html in this case.
pps: you may have to tune this regexp for specific cases.