[GIS] OpenLayers 3 custom control doesn’t get the map object

openlayers

I've been playing around with extending controls in OpenLayers 3. I've built a control which grabs a legend image from a mapserver with a GetLegendGraphics request. However, when I add the control to the map, the map object doesn't get passed to the control. I think the inheritance works just fine, because the control does have a getMap() function, but it returns undefined. Does anyone have an idea what am I doing wrong?

Code:

var ol3_legend = function(e) {
    var options = e || {};
    var wmsVersion = options.wmsVersion || '1.3.0';
    var format = options.format || 'image/png';
    var legendP = document.createElement('p');
    legendP.innerHTML = 'Legend:';
    var legendDiv = document.createElement('div');
    legendDiv.className = options.class + ' ol-unselectable';
    legendDiv.appendChild(legendP);
    var layers = this.getMap().getLayers().getArray();
    for (var i=0;i<layers.length;i++) {
        if (layers[i].get('showLegend') === true) {
            try {
                var url = layers[i].getSource().getUrls()[0];
            }
            catch(err) {
                var url = layers[i].getSource().getUrl();
            }
            var legendImg = document.createElement('img');
            legendImg.src = url + '&version=' + wmsVersion + '&service=WMS&request=GetLegendGraphic&sld_version=1.1.0&layer=' + layers[i].getSource().getParams().layers + '&format=' + format;
            legendDiv.appendChild(legendImg);
        }
    }
    ol.control.Control.call(this, {
        element: legendDiv
    });
}
ol.inherits(ol3_legend, ol.control.Control);

ol3_map.addControl(new ol3_legend({
    class: 'ol_legend'
}));

Output:

Uncaught TypeError: Cannot read property 'getLayers' of undefined

Workaround (just the modified lines):

var layers = options.map.getLayers().getArray();

ol3_map.addControl(new ol3_legend({
    map: ol3_map,
    class: 'ol_legend'
}));

The problem is, that I have to provide the map object, which makes restrictions if I would like to reuse the code later.

Working fiddle.

Best Answer

The problem is that you are using getMap() in the constructor of your control. But at the moment you instantiate the control, it is not yet added to the map. So, getMap() returns undefined.

You can overwrite setMap(map) in your control which is called by the map when executing map.setControl().

ol3_legend.prototype.setMap = function(map) {
  ol.control.Control.prototype.setMap.call(this, map);
  console.log(map);
};
Related Question