Reputation: 2837
Need to create a hover effect on my map, I'm doing it according to this tutorial: https://docs.mapbox.com/mapbox-gl-js/example/hover-styles/
Unfortunately i I came up with an error which Im not able to solve, please see below the error stack:
Uncaught TypeError: Cannot read property 'setFeatureState' of undefined
at r.<anonymous> (Map.js:219)
at r.delegates.o.<computed> (mapbox-gl.js:23210)
at r.St.fire (mapbox-gl.js:915)
at HTMLDivElement.<anonymous> (mapbox-gl.js:23021)
Please see also the photo of the error page:
I am adding the source code below:
setMapLayer(){
if (!this.map.loaded() || this.state.searchedPhrase === '') return
var contours = importContours(this.state.mapType)
var contoursWithData = addData(contours, this.state.mapType, this.state.searchedPhrase)
contoursWithData.then((data)=>{
var mpSource = this.map.getSource("contours")
if (typeof mpSource === 'undefined')
this.map.addSource('contours', { type: 'geojson', data })
else
this.map.getSource("contours").setData(data)
var mpLayer = this.map.getLayer("contours")
if (typeof mpLayer === 'undefined') {
this.map.addLayer({
id: 'contours',
type: 'fill',
source: 'contours',
layout: {},
paint: {
'fill-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
0.7,
0.4
]
}
}, 'country-label-lg')
this.map.addLayer({
id: 'state-borders',
type: 'line',
source: 'contours',
layout: {},
paint: {
'line-color': '#c44cc0',
'line-width': 0.5
}
})
}
var hoveredStateId = null
// When the user moves their mouse over the state-fill layer, we'll update the
// feature state for the feature under the mouse.
this.map.on('mousemove', 'contours', function(e) {
if (e.features.length > 0) {
if (hoveredStateId) {
console.log('hoveredStateId ',hoveredStateId)
this.map.setFeatureState(
{ source: 'contours', id: hoveredStateId },
{ hover: false }
)
}
console.log('e.features[0]',e.features[0])
console.log('e.features[0].id',e.features[0].id)
hoveredStateId = e.features[0].id
console.log('s',hoveredStateId)
this.map.setFeatureState(
{ source: 'contours', id: hoveredStateId },
{ hover: true }
)
}
})
// When the mouse leaves the state-fill layer, update the feature state of the
// previously hovered feature.
this.map.on('mouseleave', 'contours', function() {
console.log('jestem 2')
if (hoveredStateId) {
this.map.setFeatureState(
{ source: 'contours', id: hoveredStateId },
{ hover: false }
)
}
hoveredStateId = null
})
console.log('jestem 3 ',hoveredStateId )
this.setLegend(data)
this.setFill()
})
}
the console.logs are added for my debugging.
Does anyone see the problem?
Upvotes: 2
Views: 4480
Reputation: 3690
It's because you are making a new function and creating a new instance of this
. Change it to an arrow function -
this.map.on('mousemove', 'contours', (e) => { //arrow function//
if (e.features.length > 0) {
if (hoveredStateId) {
console.log('hoveredStateId ',hoveredStateId)
this.map.setFeatureState(
{ source: 'contours', id: hoveredStateId },
{ hover: false }
)
}
console.log('e.features[0]',e.features[0])
console.log('e.features[0].id',e.features[0].id)
hoveredStateId = e.features[0].id
console.log('s',hoveredStateId)
this.map.setFeatureState(
{ source: 'contours', id: hoveredStateId },
{ hover: true }
)
}
})
you will face same error in function that follows the above function change it to an arrow function as well -
this.map.on('mouseleave', 'contours', () => {
console.log('jestem 2')
if (hoveredStateId) {
this.map.setFeatureState(
{ source: 'contours', id: hoveredStateId },
{ hover: false }
)
}
hoveredStateId = null
})
console.log('jestem 3 ',hoveredStateId )
this.setLegend(data)
this.setFill()
})
Upvotes: 3