How do I parse URL params after a hash with Angularjs?
Asked Answered
T

4

22

I'm trying to parse for the access_token from Foursquare where the URL is like this:

https://mywebsite.com/4sqredirect/#access_token=1234567890XXXXX

I've tried $routeParams and $location and get nothing returned. Only after I tried $route, I did get an object back with the following attribute in it:

current:  { 
    params:  {  } 
    pathParams:  {  } 
    loadedTemplateUrl: partials/4sqredirect
    locals:  {  } 
    scope:  { 
        this:  { 
            $ref: $["current"]["scope"]
        } 
        route:  { 
            $ref: $
        } 
        location:  {  } 
        token: null
    }
} 

Does this mean there's no way to get it using native AngularJS functions cause of the hash?

UPDATE:

my controller looks like as follows:

angular.module('myApp')
    .controller('4sqredirectCtrl', function ($scope, $route, $location, $routeParams) {
        $scope.route = $route;
        $scope.location = $location;
        $scope.token = $routeParams.access_token;
    });

my main js looks like as follows:

angular.module('myApp', [
    'ngCookies',
    'ngResource',
    'ngSanitize',
    'ngRoute'
])
.config(function ($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);

    $routeProvider
    .when('/', {
        templateUrl: 'partials/main',
        controller: 'MainCtrl'
    })
    .when('/4sqredirect/', {
        templateUrl: 'partials/4sqredirect',
        controller: '4sqredirectCtrl'
    })
    .otherwise({
        redirectTo: '/'
    });
});
Tuna answered 2/1, 2014 at 7:30 Comment(0)
P
40

From angular location service $location.hash() method return #after-hash

so if your url is look like

https://mywebsite.com/4sqredirect/#access_token=1234567890XXXXX

then

$location.hash() return access_token=1234567890XXXXX

you need to split it split('=')[1]

see this plunker when you click 4Square then $location.url() return

/4sqredirect/#access_token=123456
$location.hash().split('=')[1]

return 123456

Proportion answered 2/1, 2014 at 9:20 Comment(4)
This worked great. What was the major part of my problem is a stupid error on my part. I was trying to use $location or $location.hash by themselves and not calling them.. eg. $location.hash(). Yet, while $location.hash() worked, $location.search() still returned nothing... Nevertheless, my question seemed answered by this.Tuna
Calling $location.hash() returns everything after the hash, but not the hash itself. In your provided example, it would return after-hash, not #after-hash.Communal
$location wasn't defined for me, but window.location.hash.split did the trick!Wurster
This works better than split, when available and needed... var searchParams = new URLSearchParams($location.hash()). Then you can use, searchParams.get('access_token'). Ref: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams.Quacksalver
D
9

Use $location.search()

//e.g. url https://www.example.com/#!?name=123
var s = $location.search();
// {name: '123'}

http://docs.angularjs.org/api/ng.$location

Search:

Returns search part (as object) of current url when called without any parameter.

Duval answered 2/1, 2014 at 10:18 Comment(3)
This didn't work. $location.search returned nothing. perhaps since the URL doesn't have a '?', it doesn't parse it?Tuna
Of course, if it doesn't have it then it's not a search. Add '?'Attend
Unfortunately I can't add a ? since that part is predefined and returned to me.Tuna
R
0

I'm not aware of a "native angular" way to do it, but you do have access to the hash via location.hash as a string type. it's probably not ideal, but it's workable.

Reredos answered 2/1, 2014 at 7:37 Comment(3)
Location is also null so I don't even have a location.hash.Tuna
I'm not 100% sure, but location should always reflect the browser's current location. What are you attempting to do with the access token? and, is it being returned after the hash by 4sq or by you? I would have assumed it came as a query string parameter.Reredos
It's returned by 4sq. developer.foursquare.com/overview/auth "If a user accepts, they will be redirected back to YOUR_REGISTERED_REDIRECT_URI/#access_token=ACCESS_TOKEN"Tuna
G
0

There is in fact no direct support from Angular JS to do this. I wouldn't use ngRoute, because it already might expect the # at a different place. A simple solution to your problem is to use the location.hash and the substring() function:

<!DOCTYPE html>
<html ng-app="app">

<head>
<script src="http://code.angularjs.org/1.2.6/angular.js"></script>
<link href="style.css" rel="stylesheet" />
<script>
angular.module('app', [])
.controller('AppCtrl', ['$scope', '$window', function($scope, $window) {
  $scope.accessToken = $window.location.hash.substring(14);
}]);
</script>
</head>

<body ng-controller="AppCtrl">
<h1>Access Token</h1>
<p>{{accessToken}}</p>
</body>

</html>
Georgie answered 2/1, 2014 at 8:35 Comment(1)
You and Reza had somewhat the same idea that worked. I liked Reza's more as it used the $location service rather than then the $window service.Tuna

© 2022 - 2024 — McMap. All rights reserved.