0

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:

  1. Type an address on the homepage and click the search button.
  2. Click a county name on the homepage.
  3. Enter a URL with the map coordinates (e.g. http://www.myapp.com/map#10/39.4378/-76.5841).
  4. 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?

1 Answers1

0

perhaps

var curHash = location.hash?location.hash.substring(1);
if (hash!=curHash) location.replace(
  curHash?location.href.split("#")[0]+"#"+hash:location.href+"#"+hash
);
mplungjan
  • 169,008
  • 28
  • 173
  • 236