[GIS] Geoserver WFS GeoJSON layer in Leaflet, having trouble diagnosing ‘Uncaught TypeError: undefined is not a function (Anonymous Function)’ error

errorgeojsongeoserverjavascriptleaflet

Pardon me if this has been addressed, I searched as far as I could for similar errors.

I'm trying to serve a large amount of polyline data as a geoJSON layer from GeoServer to a Leaflet instance.

HTML code:

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8'>
    <title>Pipeline Data Sample - Harris County</title>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
    <style type="text/css">
        body { margin-top: 1.0em; background-color: #444; font-family: Helvetica, Arial, FreeSans, san-serif; color: #ffffff; }
        #container { margin: 0 auto; width: 700px; }
        h1 { font-size: 3.8em; color: #809bc0; margin-bottom: 3px; }
        h1 a { text-decoration: none }
        h2 { font-size: 1.5em; color: #809bc0; }
        h3 { text-align: center; color: #809bc0; }
        a { color: #809bc0; }
        .description { font-size: 1.2em; margin-bottom: 30px; margin-top: 30px; font-style: italic;}
        .download { float: right; }
        #map { width: 700px; height: 600px; border: 1px solid #ccc }
        /* one selector per rule as explained here : http://www.sitepoint.com/html5-full-screen-api/ */
        #map:-webkit-full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
        #map:-moz-full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
        #map:full-screen { width: 100% !important; height: 100% !important; z-index: 99999; }
        .leaflet-pseudo-fullscreen { position: fixed !important; width: 100% !important; height: 100% !important; top: 0px !important; left: 0px !important; z-index: 99999; }
        .leaflet-control-zoom-fullscreen { background-image: url(https://github.com/brunob/leaflet.fullscreen/raw/master/icon-fullscreen.png); }
        .leaflet-retina .leaflet-control-zoom-fullscreen { background-image: url(https://github.com/brunob/leaflet.fullscreen/raw/master/icon-fullscreen-2x.png); background-size: 26px 26px; }
    </style>
    <script src="jquery-2.1.1.min.js"></script>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <script src="Control.FullScreen.js"></script>

</head>

<body>


    <div id="container">

        <h1>Pipeline Data Sample</h1>

        <div class="download">
            <a href="/harris_sample_shapefile.zip">
            <img border="0" width="90" src="https://github.com/images/modules/download/zip.png"></a>
            <a href="/harris_sample_shapefile.tar">
            <img border="0" width="90" src="https://github.com/images/modules/download/tar.png"></a>
        </div>

        <div class="description">
            <p>This is a sample  of <a href="http://www.aprivateurl.com/">A Company's</a>'s pipeline data in Harris County, Texas.</p>
            <p>Get all the details at <a href="http://pipelines.aprivateurl.com/">A Company's Pipeline Product website</a>.</p>
        </div>

        <div id="map"></div>

    </div>

    <script src="harris.js"></script>      

</body>
</html>

And the Javascript:

var pipemaxzoom = 18; 
var geojsonpipes = new L.GeoJSON();

function loadGeoJson(data) {
    console.log(data);
    geojsonpipes.addData(data);
    map.addLayer(geojsonpipes);
};

map.on('moveend', function() {
 if(map.getZoom() > pipemaxzoom){
    var geoJsonUrl ='http://www7.aprivateurl.com:8080/geoserver/ows'; 
    var defaultParameters = {
        service: 'WFS',
        version: '1.0.0',
        request: 'GetFeature',
        typeName: 'Pipeline:harris_master_dist',
        maxFeatures: 500,
        outputFormat: 'application/json'
        };

    var customParams = {
        bbox: map.getBounds().toBBoxString(),
        };
    var parameters = L.Util.extend(defaultParameters, customParams);
    console.log(geoJsonUrl + L.Util.getParamString(parameters));

    $.ajax({
        url: geoJsonUrl + L.Util.getParamString(parameters),
        dataType: 'jsonp',
        jsonpCallback: 'parseResponse',
        success: loadGeoJson
    });
    }else{
    map.removeLayer(geojsonpipes);
    };
});

The error I receive in the debugging console in Chrome is

Uncaught TypeError: undefined is not a function (anonymous function)

for harris.js:10

I have a feeling this has something to do with the method by which I reference leaflet.js in the HTML and my own script, that perhaps leaflet functions are not being referenced properly?

Best Answer

You need to initialize your map object. See the source code here for an example: http://leafletjs.com/examples/quick-start-example.html

Add something like this to harris.js before you call map.on.

var map = L.map('map').setView([51.505, -0.09], 13);

What's happening is map.on is undefined. Map itself is not defined in JavaScript, but by default DOM elements with IDs are automatically available in JavaScript (at least in Chrome). This is why you're not getting a "map undefined" error. The map DOM element doesn't have the method 'on' but you're accessing it as a function, which is where the error comes from.

Just initialize map and the error should go away.