Angular JS: URL parameter appears before the `#!/` and doesn't appear in $location.search()
You just need to use window.location.search
> window.location.search
> "?returnUrl=/original/location/"
$location.search()
gives you values only if your route has defined it.
What is going on here? And why is the URL parameter before the #!/login?
You can think of querystring parameters before the #! as a server-side parameters, and querystring parameters after the #! as client-side parameters. This is perfectly valid:
http://example.com?serverParam=client1#!angularRoute?angularParam=someValue
The server-side parameters allow you to configure how the page is served from the server and then, once server page is served and the Angular app is loaded, use the client-side parameters to supply what that particular Angular app is expecting.
Why does this prevent $location.search() from returning anything? If I move the param to the end of the resulting URL, it works.
Because nothing was specified for the client-side parameters until you moved the values there.
What can I do to fix this?
- You could change the links to be like how you modified them to get them to work:
<a href="example.com/path/to/app/#!/login?returnUrl=/original/location">Login.</a>
or duplicate the parameter so it's available on both the server and the client<a href="example.com/path/to/app/?returnUrl=/original/location#!/login?returnUrl=/original/location">Login.</a>
- You can inject
$window
and get the server-side values from$window.location.search
- You can inject
$location
and use$location.absUrl()
Here is an example of how you can set the client-side parameters from the server-side parameters:
var app = angular.module('YOURAPPNAME', []);
app.run(['$location', function($location) {
// I'm going to fake out the url so it runs in the SnippetEditor.
var url = "example.com/path/to/app?returnUrl=/original/location/#!/login"; //$location.absUrl();
var hashbangIdx = url.indexOf('#!');
var serverStr = hashbangIdx > -1 ? url.substring(0, hashbangIdx) : url;
var qIdx = serverStr.indexOf("?");
var p = qIdx > -1 ? serverStr.substring(qIdx).split(/[&||?]/) : [];
for (var i = 0; i < p.length; i += 1) {
if (p[i].indexOf('=') > -1) {
var param = p[i].split('=');
$location.search(param[0], param[1]);
}
}
}]);
app.controller('MainCtrl', ['$scope', '$location', function($scope, $location) {
$scope.params = $location.search();
}]);
<!DOCTYPE html>
<html ng-app="YOURAPPNAME">
<head>
<meta charset="utf-8" />
<title>AngularJS</title>
<script data-require="[email protected]" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<h4>Parameters:</h4>
<p ng-repeat="(name, val) in params">
{{name}}: {{val}}
</p>
</body>
</html>