Tech Stack
AngularJS v1.2.28 - cannot change this
Angular Leaflet Directive
Leaflet 1.0.0-beta.2
Esri Leaflet v2.0.0-beta.6
Intro
I've run into some trouble. I'm trying to use leaflet-hash.js as a way to allow users to share their location with others. The problem is that I can get the hash to appear in the URL if I change location.replace(hash)
. But a few problems occur depending on what I change it to. Below I outline what I'm trying to achieve and what I've already tried and the outcome.
Desired Behavior
The user should be able to access the map page in 4 ways:
- Type an address on the homepage and click the search button.
- Click a county name on the homepage.
- Enter a URL with the map coordinates (e.g. http://www.myapp.com/map#10/39.4378/-76.5841).
- Enter the URL for the map page without the coordinates (e.g. http://www.myapp.com/map).
The user should also be able to zoom/move around on the map page and the coordinates will change in the URL hash.
If the user only enters the generic map URL (http://www.myapp.com/map
) they are automatically taken to the statewide zoom level (http://www.myapp.com/map#8/38.903/-76.776
).
The Problem
My problem only concerns numbers 3 and 4 above.
Using the plugin as-is I am redirected back to the homepage regardless of which of the 4 methods above I use. I believe this bit of code is the culprit:
location.replace(hash);
If I change it to:
location.hash = hash;
the hash will appear in the URL but I get the following error and constant page refreshing when I try to access the map page using method 4:
[$rootScope:infdig] 10 $digest() iterations reached. Aborting!
If I change the line to:
location.hash.replace(hash);
I won't get the digest error or the constant page refreshing but the hash isn't in the URL like it should be
(e.g. http://www.myapp.com/map
instead of http://www.myapp.com/map#10/39.4378/-76.5841
)
This happens regardless of whether I use access method 3 or 4.
My Code
On map load I check for the presence of # and then determine what, if any, geometry I should also be displaying:
leafletData.getMap("map").then(function(map) {
$scope.map = map;
var hash = new L.Hash($scope.map);
var checkLocation = window.location.href;
//No # in URL
if (checkLocation.indexOf("#") <= 0) {
if (searchResults.geojson) {
// dealing w/ polygon
// CODE TO DISPLAY POLYGON
} else if (searchResults.latlng) {
// dealing w/ point
// CODE TO DISPLAY POINT
} else {
// no geometry so go with default view
// CODE TO DISPLAY DEFAULT VIEW
}
}
// # in URL
else {
var url = decodeURIComponent(window.location.href);
if (searchResults.geojson) {
// dealing w/ polygon
// CODE TO DISPLAY POLYGON
} else if (searchResults.latlng) {
// dealing w/ point
// CODE TO DISPLAY POINT
} else {
// no geometry so go with default view
var n = url.lastIndexOf('#');
var hashOnly = url.substring(n);
var mapView = parseUrlHash(hashOnly);
console.log(mapView);
$scope.map.setView([mapView.lat, mapView.lng], mapView.zoom);
}
}
});
Leaflet Hash Plugin Code
I've only posted the part I think is relevant along with my comments. The full code can be found here: leaflet-hash.js
onMapMove: function() {
// bail if we're moving the map (updating from a hash),
// or if the map is not yet loaded
if (this.movingMap || !this.map._loaded) {
return false;
}
var hash = this.formatHash(this.map);
hash = decodeURIComponent(hash);
if (this.lastHash != hash) {
//[A] Original code
// Automatically redirects you back to the home page
//location.replace(hash);
//[B] Suggestion from GitHub
//https://github.com/mlevans/leaflet-hash/issues/45
// Shows hash in URL but causes this: Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
// and constant page refreshing when trying to access map page using method 4.
location.hash = hash;
//[C] Fixes errors in [B] but hash does not appear in the URL
// I need it to be in the URL so users can share location
//location.hash.replace();
//[D] Same as [C]
//location.hash.replace(hash);
this.lastHash = hash;
}
},
I'm not sure where I'm going wrong. I thought the problem might be in the plugin but perhaps my code is what's causing it?
UPDATE
In app.js I have $locationProvider.html5Mode(true);
. Could this be causing a conflict?