AngularJS remove URL parameter with HTML5Mode = false - angularjs

I type url and press enter http://myservertest.com?auth=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
This one will call a service with auth param to authenticate, after authorization is successful, I want my url should be like this http://myservertest.com/mainpage without refresh app controller again.
I tried windows.location = "/" then it will refresh the page.
How can I do without refresh APP Controller ?

Just in case someone stumbles about this again after I stumbled about this after 7 years:
Usually you solve it by using $location:
$location.url('<url>');
$location.replace();
But... default html5Mode this will not replace window.location.search query parameters like
http://localhost/path?auth=xxx&andso=on
Without html5Mode (enabled:false by default) you need to care about pushState yourself before the AngularJs application runs:
Solution is to use...
window.history.replaceState(null, window.name, window.location.origin + window.location.path + window.location.hash)
(an example replacing the currently shown location url without parameters)
.. in an angular.provider() or angular.config():
In a provider when offering a reusable service:
angular.module('app').provider('AuthService', [
'someConfig',
function(someConfig){
if (someConfigObject.doItBeforeStartup) {
// ... check for parameter in window.location.search or whatever
window.history.replaceState(null, window.name, window.origin + window.path + window.hash)
}
this.readQuery = function(cfg){./* you can do it also here and call it in config*/..}
this.$get = ...
}]);
and/or in an config when using providers:
angular.module('app').config([
'AuthServiceProvider',
'someConfig',
function (AuthServiceProvider, someConfig) {
window.history.replaceState(.....)
// or in
// AuthServiceProvider.readQuery(...)
}]);

Related

AngularJS ngRoute - specify data for target page, with data not appearing in URL

I'm using AngularJS and I would like to redirect a user when he clicks a button on /page1 to /page2. I currently use AngularJS routing for this using ngRoute which works all fine. However, in addition to the redirection, I would also like to pass some data from page1 to page2 to pre-populate some of the HTML on page2. I know that in order to pass such data, I can either specify it in the path parameter,e.g.
/page2/<param1>/<param2>
or as a query string parameter, e.g.
/page2?<key1>=<value1>&<key2=value2>
In both ways, I can retrieve the query string or path params in /page2 using $route.current.params
However, I do not want to do either of the above as I do not want to expose my data on the URL to the user. Is there a way in AngularJS that the parameters can be passed to /page2, such that they are "hidden" from the URL?
Thanks
You can use a service to store data that will survive route changes. Services are singletons that persist through the entire life of the app.
app.service("appData", function() {
var myData;
this.set = function(data) {
myData = data;
};
this.get = function() {
return myData;
};
}
In a controller:
app.controller("viewCtrl", function($scope,appData) {
$scope.myData = appData.get();
//
appData.set(newData);
});
For more information, see AngularJS Developer Guide - Creating Services.

How to redirect using ajax in angularjs

I want to redirect a user on specific page using ajax call in angularjs. I am able to redirect using below mentioned code but when i again want to redirect user to root page i am unable to do so as the value of $window.location.href+ 'getTechnicianWorkOrder/'+woId is persisting as is:
$scope.getTechnicianWorkOrderFormURL = function(woId){
return $window.location.href + 'getTechnicianWorkOrder/'+woId;
};
Another place where i want to redirect to root page:
$scope.getAssignedListURL = function(){
return $window.location.href;
};
Note: i want to make this redirection work even in offline mode of HTML5 cache-manifest.
Using the $location service.
$location.path('/');
The answer by #prashant-palikhe is the right one, $location.path('/'); is the route to your root path. just use the dependency of $location to your controller like this:
yourapp.controller('YourController', ['$location', function($location) {
...
}
I always use the ui.router for my routes and in there you can add $urlRouterProvider.otherwise('/') for fallback in any unknown state or route.
In some cases you can add something like this in your states:
resolve : {
dataObj : ['$http', function($http) {
return $http({method : 'GET', url : '/your/ajax/endpoint'})
;}],
},
onEnter : ['dataObj', '$state', function(dataObj, $state) {
// dataObj is your ajax response object. Based on this you can redirect to a certain state of needed
$state.go('default');
}]
resolve is data that preloads data onEnter is called before entering the state. This can be used as some sort of middleware.

Get previous URL on Angular request interceptor

I'm implementing an angular page-wide authentication app.
It is an event machine that uses an interceptor, so if any request results in a 401 response, it pops a login modal. When the login succeeds, it performs the request again (which could as well result in a 403 if the logged user do not have enough privileges to access the requested resource).
So long, things are working as expected except that when the user cancels the login process, the $location.path() still points to the requested resource. I want to revert this to the previous path. So:
What I expected
I expected to be able to get the "callee" URL like so:
.factory('authInterceptor', ...
return {
// Append the authentication headers to every request
request: function(config) {
previousLocation = $location.path(); // <--- HERE
if(Session.exist) {
config.headers.Authorization = Session.token;
}
return config || $q.when(config);
},
I expected this line to give me the "callee" path, but it actually gives me the requested one (angular has changed it before performing the request).
The route provider
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/admin', {
templateUrl: "/admin"
})
.otherwise({ redirectTo: '/' });
}])
This naughty little boy is changing my path prior to the request. I guess I can do something here on resolve, but I don't find this useful, since it will completely break encapsulation, forcing me to resolve each time I call any protected resource, so I can pass the current path to some service in my auth app.
So, how can I get the previous path from the interceptor, or some service within the auth app, without explicitly sending it from the route provider configuration?
Why don't you watch $on route change events and bind your current/previous paths to a $window or global $scope variable?
I haven't read all your code above, but this is how I handle location things within my app:
$scope.$on('$routeChangeSuccess', function(evt, current, previous){
var routeData = {};
//prop: uriSegment
//desc: get all uri segments for current location
routeData.uriSegment = [];
routeData.uriSegment = $location.path().substr(1).split('/');
//prop: urls
//desc: get current & previous urls
routeData.urls = {};
routeData.urls.curr = $location.url().substr(1);
//...previous url
if(previous && previous.originalPath){
//remove matching structure & slashes from url & add params as plain values
var prevUrl = previous.originalPath.substr(1).replace('/:', '/').replace(':', '');
if(previous.pathParams){
angular.forEach(previous.pathParams, function(val, key){
prevUrl = prevUrl.replace(key, val);
});
}
routeData.urls.prev = prevUrl;
}
//bind routeData to scope/window...
$scope.uriSegment = routeData.uriSegment;
$scope.urls = routeData.urls;
});
How does it work:
1. Get current & previous url:
$scope.urls.curr //shows current url
$scope.urls.prev //shows previous url
... if your route is defined like /admin/:userID and you are on that page, the url will contain that specific userID, it won't return the param name. /admin/53 will be /admin/53.
2. Get a specific url segment from current url:
$scope.uriSegment[1]
... for current url like /admin/53 will print 53
There were a lot more things in the above code, but I think that's what you need - to remember the previous url. You can play with route events and build your own.
I see that you inject $routeScope in your factories, so you can add my code in your main controller and update the $routeScope with routeData on every route change and then you can go like this:
...
previousLocation = $rootScope.urls.prev;
...
More about route events here.

Dynamic route request render not working, backend express

I want to try dynamic route request but It's not working properly. And here I explain my coding style step by step.
<nav class="main-nav" ng-show="global.user.user_type!='admin'" ng-repeat="mMenu in Mainmenu">
{{mMenu.MenuName}}
</nav>
This code contain URL link and It's load every time with a variable that is web address link. And the link is something like that - http://localhost/views/adminpanel/about.html
In AngularJS Controller contain the code -
$scope.geturl = function(url)
{
var params = {
url1 : '/views/adminpanel/'+url
}
$http({'method' : 'post', url : 'views/adminpanel/'+url, data: params
}).success(function(data)
{
}).
error(function(data){
})
}
configuring and using ngRoute -
when('/views/adminpanel/:url', {
controller: 'homeCntrl',
templateUrl: 'views/adminpanel/:url'
})
In server side (Express) :
Routing HTTP requests, Configuring middleware and Rendering HTML views
app.post('/views/adminpanel/:url',auth.requiresLogin, users.geturl);
exports.geturl= function(req,res)
{
var url = req.body.url1;
res.render(url);
}
This is all about my rendering process but It's not working. In browser It only shows the URL link but not shows any content. How can I solve It any idea?
I think you are confusing things:
first of all you have a link together with a ngClick: you should have either of those
your ngClick has an empty success function, so it does nothing with the template
you have a route set with express that matches with the ngRoute (btw, POST is usually used to create resources, you should GET the template)
your templateUrl is going to send a GET request to (literally) /views/adminpanel/:url, it does not replace :url
To fix it:
set a different endpoint for your APIs
use a GET endpoint instead of a POST
change the ngRoute to:
when('/views/adminpanel/:url', {
controller: 'homeCntrl',
templateUrl: function(param) {
return '/api/<path>/' + param.url;
}
})
remove the ngClick from the <a>

Case insensitivity with angularjs ui-router

I'm building a new angularJS app, based from the AngularJS SPA Visual studio template (http://visualstudiogallery.msdn.microsoft.com/5af151b2-9ed2-4809-bfe8-27566bfe7d83)
this uses ui-router (https://github.com/angular-ui/ui-router) for its routing.
however, it seems to be case sensitive.
Any idea how I would instruct angular/ui-router to ignore the case of the url parameter?
case sensitivity doesn't matter while in the app, though should a user type a url to enter the application at a specific page, we need to ensure that about is also the same as aBouT
Cheers
You can now configure ui-router to be case insensitive directly. Here is how you can use it:
angular.module('main', ['ui.router']);
angular.module('main').config(['$urlMatcherFactoryProvider', '$stateProvider', '$urlRouterProvider',
function($urlMatcherFactory, $stateProvider, $urlRouter) {
$urlMatcherFactory.caseInsensitive(true);
$urlMatcherFactory.strictMode(false);
$stateProvider.state('foo', {
url: '/foo',
template: '<b>The Foo View</b>'
});
$stateProvider.state('bar', {
url: '/bar',
template: '<b>The Bar View</b>'
});
$stateProvider.state('nomatch', {
url: '/nomatch',
template: '<b>No match found View</b>'
});
$urlRouter.otherwise('/nomatch');
}
]);
In the latest release (0.2.11), this is broken. A fix has been pushed already that can be seen at Github. So, currently, the best solution is to clone ui-router and build the head of master manually. Alternatively, you can just alter the source manually until the next release comes.
UPDATE (11/18/2014):
A release has now been made that incorporates the fix from above so that you no longer have to pull source and build manually. You can view the release on Github or just get the latest build.
Following the link in the comments to the original question, i was able to get the answer I needed.
Before my $stateProvider.state(......) routes I now have this piece of code:
$urlRouterProvider.rule(function ($injector, $location) {
//what this function returns will be set as the $location.url
var path = $location.path(), normalized = path.toLowerCase();
if (path != normalized) {
//instead of returning a new url string, I'll just change the $location.path directly so I don't have to worry about constructing a new url string and so a new state change is not triggered
$location.replace().path(normalized);
}
// because we've returned nothing, no state change occurs
});
Essentially it will toLowerCase() a url that isn't all lowercase already.
Once done, it replaces the url rather than redirects. Then carries on with matching a state.
You shouldn't change how ui-route handles URL matching to accept case insensitive URLs (that will have unexpected problems), but you can attempt to correct URLs for the user automatically when the routes fail.
When ui-route can not match a URL to a route it triggers the otherWise() callback. I'll show you have to redirect using this callback.
The following makes the assumption that all URLs for your app should be in lower case.
var stateHandler = function($urlRouterProvider)
{
$urlRouterProvider.otherwise(function($injector, $location)
{
var url = $location.absUrl();
var redirect = url.toLowerCase();
if(url == redirect)
{
return;
}
$window.location = redirect;
});
};
YourAngularApp.config(['$urlRouterProvider',stateHandler]);
If you need more control, then use a regex to select which URLs need rewriting.
According to official wiki,
https://github.com/angular-ui/ui-router/wiki/URL-Routing
Darren's answer looks right:
app.config(function ($urlRouterProvider) {
// Here's an example of how you might allow case insensitive urls
$urlRouterProvider.rule(function ($injector, $location) {
//what this function returns will be set as the $location.url
var path = $location.path(), normalized = path.toLowerCase();
if (path != normalized) {
//instead of returning a new url string, I'll just change the $location.path directly so I don't have to worry about constructing a new url string and so a new state change is not triggered
$location.replace().path(normalized);
}
// because we've returned nothing, no state change occurs
});}

Resources