Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Calculadora

0

119
Vistas
Leaflet JS: defining update function within promise; variation on tutorial

A variation on this tutorial: https://leafletjs.com/examples/choropleth/. I am attempting to add custom info control.

let info = L.control();
function highlightFeature(e) {
    ...
    info.update(layer.feature.properties);
}

function resetHighlight(e) {
    ...
    info.update();
}

function updateFunction(tab, props) {
    this._div.innerHTML = '<h4>US Active Covid-19 Cases </h4>' +  (props ?
        '<b>' + props.name + '</b><br />' + getActive(tab, props.name) + ' cases'
        : 'Hover over a state');
}

info.onAdd = function(map) {
    this._div = L.DomUtil.create("div", "info");
    this.update();
    return this._div;
}

let statedata = fetch(url + stateurl).then(data => data.json());
statedata.then((data) => {
    info.update = (props) => updateFunction(data, props);
    let style = (feature) => styleMap(data, feature); 
    info.addTo(mymap);

    geojson = L.geoJson(statesData, {style : style, onEachFeature: onEachFeature}).addTo(mymap);    
});

Here, my info.update is slightly different from the tutorials. info.update and style depend on the json data that I am only able to access inside the asynchronous section on the bottom. However, this code gives me the following error: Uncaught (in promise) TypeError: Cannot set property 'innerHTML' of undefined, referring to the this._div line of the updateFunction.

I found that if I do either of the following

  1. move let info = L.control() and all of my functions that depend on info inside the promise or
  2. define info.update outside of the promise,

then the code will work without error. However, option 1 appears hideous and morally incorrect, and option 2 necessitates that I abandon hope of accessing the statedata json. Also, in option 2, I don't understand what difference it makes declaring info.update inside or outside the promise. In particular, why declaring info.update inside the promise leads to undefined behavior with info._div and declaring info.update outside the promise does not?

Any clues as to what is wrong here would be greatly appreciated!

7 months ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

In the tutorial you're working from, this is what they have for info.update:

info.update = function (props) {
    this._div.innerHTML = '<h4>US Population Density</h4>' +  (props ?
        '<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
        : 'Hover over a state');
};

In this function, this will refer to the info object. In your code you refactor to this:

function updateFunction(tab, props) {
    this._div.innerHTML = '<h4>US Active Covid-19 Cases </h4>' +  (props ?
        '<b>' + props.name + '</b><br />' + getActive(tab, props.name) + ' cases'
        : 'Hover over a state');
}
// ...
info.update = (props) => updateFunction(data, props);

By using an arrow function that invokes a regular function, you've effectively cut the ties between info and this. In your case, this is probably defaulting to window, which would explain why _div is undefined.

To fix this you need to explicitly bind this to info. You could do this:

info.update = (props) => updateFunction.bind(info)(data, props);

Or even more concise, you can simply bind this and the first argument, and skip the arrow function intermediate altogether:

info.update = updateFunction.bind(info, data);
7 months ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar empleo Planes Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2023 PeakU Inc. All Rights Reserved.