JavaScript Cannot read property [Résolu]

Signaler
Messages postés
887
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
22 février 2021
-
Messages postés
887
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
22 février 2021
-
Bonjour,
Je ne comprends pas cette erreur, voici ce que donne la console

Map3.html?map=PilotePrive/Itineraires/Itineraires.xml:42 Uncaught TypeError: Cannot read property 'resetStyle' of undefined
at e.resetHighlight (Map3.html?map=PilotePrive/Itineraires/Itineraires.xml:42)
at e.fire (leaflet.js:5)
at e._fireDOMEvent (leaflet.js:5)
at e._handleDOMEvent (leaflet.js:5)
at HTMLDivElement.r (leaflet.js:5)
resetHighlight @ Map3.html?map=PilotePrive/Itineraires/Itineraires.xml:42
fire @ leaflet.js:5
_fireDOMEvent @ leaflet.js:5
_handleDOMEvent @ leaflet.js:5
r @ leaflet.js:5

Map3.html?map=PilotePrive/Itineraires/Itineraires.xml:46 Uncaught TypeError: Cannot read property 'name' of undefined
at e.popup (Map3.html?map=PilotePrive/Itineraires/Itineraires.xml:46)
at e.fire (leaflet.js:5)
at e._fireDOMEvent (leaflet.js:5)
at e._handleDOMEvent (leaflet.js:5)
at HTMLDivElement.r (leaflet.js:5)
popup @ Map3.html?map=PilotePrive/Itineraires/Itineraires.xml:46
fire @ leaflet.js:5
_fireDOMEvent @ leaflet.js:5
_handleDOMEvent @ leaflet.js:5
r @ leaflet.js:5

et voici le code, j'ai indiqué où se trouvent les lignes 42 et 46
function highlightFeature(e) {
    var layer = e.target;

    layer.setStyle({
        weight: 5,
        color: '#666',
        dashArray: '',
        fillOpacity: 0.7
    });
    if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
        layer.bringToFront();
    }
}
function resetHighlight(e) {
    geojson.resetStyle(e.target);   <== ligne 42
}

function popup(feature, layer) {
    if (feature.properties.name) {  <== ligne 46
      layer.bindPopup(feature.properties.name);
    }
  }
function Hoover(feature, layer) {
    layer.on({
        click: popup,
        mouseover: highlightFeature,
        mouseout: resetHighlight
    });
}
...
var customLayer = L.geoJson(null, {
  style: function(feature) {
    if (!feature.properties.id) {
      feature.properties.id = n++;
    }
    var iColor = feature.properties.id % colors.length;
    return { color: colors[iColor] };
  }, 
  onEachFeature: Hoover 
});

La fonction highlightFeature fonctionne correctement.
resetHighlight et popup donnent la même erreur Cannot read property

Merci d'avance pour votre aide

5 réponses

Messages postés
31451
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 février 2021
3 276
Bonjour,

Tu utilises la lib leaflet.js
IL faut donc lire la documentation de celle ci pour apprendre à utiliser correctement les fonctions qui s'y trouvent
https://leafletjs.com/reference-1.7.1.html#geojson-resetstyle

Le problème ne provenant pas de ce code js .. mais plutôt de la façon dont tu l'as utilisé dans ta page..

En l'occurrence, pour pouvoir utiliser le resetStyle .. il faut déjà avoir déclaré un style..
 layer.on('mouseover', function (){
            this.setStyle({
                color: 'green'
            });



Messages postés
887
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
22 février 2021
4
Merci,
J'ai utilisé l'exemple que j'ai trouvé dans la documentation leafletjs ici https://leafletjs.com/examples/choropleth/ Adding Interaction.
click: popup fonctionne
mouseover: highlightFeature aussi
mais pas les 2 ensemble, je pense donc que j'ai commis une erreur de syntaxe mais je ne trouve pas laquelle
Messages postés
31451
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 février 2021
3 276 >
Messages postés
887
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
22 février 2021

Tu as utilisé l'exemple.. ok ... mais donc... ton code.. c'est quoi exactement ? ( vu que tu as visiblement fait des changements par rapport à l'exemple )
Messages postés
887
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
22 février 2021
4
Je débute avec JS, j'ai voulu combiner 3 interactions : survol de souris, fin du survol et click, c'est là que ça coince, avec un seul évènement ça fonctionne.
J'appelle donc l'interaction comme ceci
onEachFeature: Hoover

Hoover est une fonction qui combine les 3
function Hoover(feature, layer) {
    layer.on({
        click: popup,
        mouseover: highlightFeature,
        mouseout: resetHighlight
    });
}

c'est probablement là qu'est mon erreur puisque, si dans cette fonction je mets seulement popup ou highlightFeature ça fonctionne, si je mets les 2 alors popup ne fonctionne plus et donne l'erreur Cannot read property, idem avec resetHighlight.
Messages postés
31451
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
21 février 2021
3 276
Ben.. dans cette parti du code... tu n'as donc pas définit de style...
Donc le resetStyle ne peut pas marcher
layer.setStyle({
        weight: 5,
        color: '#666',
        dashArray: '',
        fillOpacity: 0.7
    });
Messages postés
887
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
22 février 2021
4
Dans l'exemple dont j'ai donné le lien il est en effet précisé
make sure our GeoJSON layer is accessible through the geojson variable by defining it before our listeners and assigning the layer to it later:
var geojson;
// ... our listeners
geojson = L.geoJson(...);

et c'est bien ce que j'ai fait (var geojson; est avant la définition des fonctions).
Messages postés
887
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
22 février 2021
4
Bon, j'ai trouvé,
évidemment si je déclare var customLayer = L.geoJson(...
puis que j'utilise geoJson.resetStyle(e.target); comme sur l'exemple ça ne fonctionne pas
je dois utiliser customLayer.resetStyle(e.target);

Par contre je ne parviens pas à mettre 2 fonctions ensemble : ceci fonctionne très bien
highlightFeature met une trace en évidence, resetHighlight rétablit le style par défaut
function Interaction(feature, layer) {
    layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight
    });
}
...
var customLayer = L.geoJson(null, {
...,
onEachFeature: Interaction

Ceci fonctionne aussi très bien pour afficher un popup quand on clique sur une trace
var customLayer = L.geoJson(null, {
 ...
  }, 
  onEachFeature: function(feature, layer) {
    if (feature.properties.name) {
      layer.bindPopup(feature.properties.name);
    }
  } 
});
mais je ne parviens pas à mettre les 2 ensemble
function popup(e) {
    layer = e.layer,
    feature = layer.feature;                <==
    if (feature.properties.name) {
      layer.bindPopup(feature.properties.name);
    }
  }
...
function Interaction(feature, layer) {
    layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight,
        click: popup
    });
}
Highlight et Reset fonctionnent bien mais quand je clique j'obtiens

Uncaught TypeError: Cannot read property 'feature' of undefined
sur la ligne en face de laquelle j'ai mis une flèche
et si je commente froidement cette ligne j'obtiens
Uncaught ReferenceError: feature is not defined sur la ligne suivante

Je pense qu'il s'agit simplement d'un passage de paramètres mais mes connaissances en JS ne sont pas suffisante pour que je comprenne mon erreur : un petit coup de main ?
Merci
Messages postés
887
Date d'inscription
mercredi 4 août 2010
Statut
Membre
Dernière intervention
22 février 2021
4
onEachFeature: function(feature, layer) {
  if (feature.properties.desc) {
    layer.bindPopup(feature.properties.desc);
  }
  layer.on({
      mouseover: highlightFeature,
      mouseout: resetHighlight
  });
}