Open jvskriubakken opened 5 years ago
Hi! Sorry for the troubles, I'll check it out shortly.
Could you provide a minimal failing code sample to speed the diagnosing up? And do you know when this was last working for you?
This might be related to the 4.0.0 release, so a late 3.x release might work as a quickfix.
Hi! Thanks for looking into this! We have setup some example code similar to what is failing by us. However we are not able to reproduce the error :( Example here: https://stackblitz.com/edit/react-zhhbjd?file=Map.js
In our build and deployment history we have found a deploy that works and the next that does not. However there is no changes in our code, or our direct dependencies that could cause this problem (only a few unrelated components where added). However we had not committed the package-lock.json into our project repo. So we suspect that we where hit by breaking changes in transitive dependencies. But what could cause map in the EnhancedLayer component to be undefined?
I can't see how any other dependencies could break this 😕
As a general suggestion, do commit in your lockfiles to avoid some headaches... But as for this issue, I don't know how to debug it, really. Could add in a check for whether map is undefined... But that case should be avoided by the Map component not rendering its children unless the map is initialized.
:( I'm trying to follow the code... and where map is set as a property into EnchancedLayer: EnchancedLayer is wrapped by function layerMouseTouchEvents, which again is given as input to withMap which passes the map property onto EnchancedLayer. And the map is received from MapContext.Consumer?
Hi again,
I see that react-mapbox-gl depends on supercluster@3.0.2 while mapbox-gl depdens on supercluster@4.1.1. Could this have any cause in this? We are using create-react-app - do you know if cra/babel/webpack manages two versions into same compiled js?
react-mapbox-gl dependency:
├─┬ react-mapbox-gl@4.0.2
│ ├─┬ @turf/bbox@4.7.3
│ │ └── @turf/meta@4.7.4
│ ├── @turf/helpers@4.7.3
│ ├── deep-equal@1.0.1 deduped
│ └─┬ supercluster@3.0.2
│ └── kdbush@1.0.1
mapbox-gl dependency:
├─┬ mapbox-gl@0.51.0
│ ├── @mapbox/geojson-types@1.0.2
│ ├── @mapbox/jsonlint-lines-primitives@2.0.2
│ ├── @mapbox/mapbox-gl-supported@1.4.0
│ ├── @mapbox/point-geometry@0.1.0
│ ├── @mapbox/tiny-sdf@1.1.0
│ ├── @mapbox/unitbezier@0.0.0
│ ├─┬ @mapbox/vector-tile@1.3.1
│ │ └── @mapbox/point-geometry@0.1.0 deduped
│ ├── @mapbox/whoots-js@3.1.0
│ ├── csscolorparser@1.0.3
│ ├── earcut@2.1.3
│ ├── esm@3.0.84
│ ├─┬ geojson-rewind@0.3.1
│ │ ├─┬ @mapbox/geojson-area@0.2.2
│ │ │ └── wgs84@0.0.0
│ │ ├─┬ concat-stream@1.6.2
│ │ │ ├── buffer-from@1.1.1
│ │ │ ├── inherits@2.0.3 deduped
│ │ │ ├── readable-stream@2.3.6 deduped
│ │ │ └── typedarray@0.0.6
│ │ ├── minimist@1.2.0
│ │ └─┬ sharkdown@0.1.0
│ │ ├─┬ cardinal@0.4.4
│ │ │ ├── ansicolors@0.2.1
│ │ │ └─┬ redeyed@0.4.4
│ │ │ └── esprima@1.0.4
│ │ ├── expect.js@0.2.0
│ │ ├── minimist@0.0.5
│ │ ├─┬ split@0.2.10
│ │ │ └── through@2.3.8 deduped
│ │ ├─┬ stream-spigot@2.1.2
│ │ │ └─┬ readable-stream@1.1.14
│ │ │ ├── core-util-is@1.0.2 deduped
│ │ │ ├── inherits@2.0.3 deduped
│ │ │ ├── isarray@0.0.1
│ │ │ └── string_decoder@0.10.31
│ │ └── through@2.3.8 deduped
│ ├── geojson-vt@3.2.1
│ ├── gl-matrix@2.8.1
│ ├── grid-index@1.0.0
│ ├── minimist@0.0.8
│ ├── murmurhash-js@1.0.0
│ ├─┬ pbf@3.1.0
│ │ ├── ieee754@1.1.12
│ │ └─┬ resolve-protobuf-schema@2.1.0
│ │ └── protocol-buffers-schema@3.3.2
│ ├── potpack@1.0.1
│ ├── quickselect@1.1.1
│ ├── rw@1.3.3
│ ├─┬ supercluster@4.1.1
│ │ └── kdbush@2.0.1
│ ├── tinyqueue@1.2.3
│ └─┬ vt-pbf@3.1.1
│ ├── @mapbox/point-geometry@0.1.0 deduped
│ ├── @mapbox/vector-tile@1.3.1 deduped
│ └── pbf@3.1.0 deduped
Hi again, I'm trying to debug the problem my self, and in context.js the map is undefined:
While earlier in the call stack map is defined:
but I have too little react knowledge to to understand where it get lost from that point to later... does this help you? Or is it any debugging hints you could give me?
I figured out that state.map is also undefined at the time when the MapContext.Provider is created:
Sorry for the delay.
The supercluster dep discrepancy should be fixed, but it's probably unrelated to this issue. In general, webpack should be able to properly resolve multiple versions of the same package.
src/map.tsx
shouldn't render out the Layer
if its state.ready = false
.
I understand this is time critical for you – please try using v3.9.2
for the time being – I believe it won't have this bug.
I now have time to properly look into it. I know there are some lacking typings here that could cause it, but couldn't confirm my specific suspicions at first glance.
Thanks a lot for your time! Downgrading to v3.9.2 solved the issue!
No problemo.
To confirm, in your real code, you have a Layer and a Feature inside the react-mapbox-gl Map component? And the Layer is conditionally rendered?
This is my map component:
<MapBox
style={'mapbox://styles/mapbox/dark-v9'}
logoPosition="bottom-right"
doubleClickZoom={false}
center={center}
fitBounds={fitBounds}
containerStyle={{
height: "100%",
width: "100%"
}}
onStyleLoad={this.handleStyleLoad}
>
{substationTooltip &&
<Popup
onMouseEnter={() => this.cancelHideSubstationTooltipTimer()}
onMouseLeave={() => this.startHideSubstationTooltipTimer()}
coordinates={substationTooltip.coordinates}
offset={15}
>
<List disablePadding={true}>
{substationTooltip.loadMetrics.map((metric, index) => {
return (
<ListItem
selected={selectedTransformer === metric.key.ownerId}
button
key={`${index}${metric.key.ownerId}`}
onClick={() => selectTransformer(metric.key.ownerId)}
>
<ListItemIcon
style={{
color: metric.peakPercentage >= 100 ? theme.asset.transformer.warningColor : theme.asset.transformer.defaultColor,
}}
>
<Lens/>
</ListItemIcon>
<ListItemText primary={substationTooltip.transformers[index].name}/>
</ListItem>
)
})}
</List>
</Popup>
}
{loadMetricData &&
<Layer type="circle"
id="substation-layer"
paint={{
'circle-color': {
'property': 'peakPercentage',
'type': 'exponential',
'default': theme.asset.substation.defaultColor,
'stops': [
[0, theme.asset.substation.defaultColor],
[99, theme.asset.substation.defaultColor],
[100, theme.asset.substation.warningColor],
[300, theme.asset.substation.warningColor]
]
},
'circle-stroke-color': {
'property': 'substationId',
'type': 'categorical',
'default': 'transparent',
'stops': [
[`${selectedSubstationIdOrZero}`, theme.map.selection.borderColor]
]
},
'circle-stroke-width': 2,
'circle-radius': {
'property': 'peakPercentage',
'type': 'exponential',
'default': 5,
'stops': [
[0, 5],
[100, 10],
[200, 15]
]
},
}}>
{substations.length > 0 &&
substations.map((substation) => {
const substationCoordinates = geometryObjectToLngLat(substation.geometryObject);
const loadMetrics = loadMetricData.loadMetrics
.filter(lm => substation.transformers.includes(lm.key.ownerId));
const loadMetricWithHighestPeakPercentage = loadMetrics.reduce((max, loadMetric) => max.peakPercentage > loadMetric.peakPercentage ? max : loadMetric);
const featureProperties = {
...loadMetricWithHighestPeakPercentage,
substationId: substation.id
};
return (
<Feature
coordinates={substationCoordinates}
properties={(featureProperties)}
id={substation.id}
key={substation.id}
transformer={loadMetricWithHighestPeakPercentage.key.ownerId}
onMouseEnter={(event) => {
event.map._canvas.style.cursor = 'pointer';
this.handleMouseEnter(
substationCoordinates,
substation.id
);
this.cancelHideSubstationTooltipTimer();
}}
onMouseLeave={(event) => {
event.map._canvas.style.cursor = '';
this.startHideSubstationTooltipTimer();
}}
onClick={() => selectTransformer(loadMetricWithHighestPeakPercentage.key.ownerId)}
/>
)
})}
</Layer>
}
</MapBox>
No problemo.
To confirm, in your real code, you have a Layer and a Feature inside the react-mapbox-gl Map component? And the Layer is conditionally rendered?
Yes, I think it's correct answer you yes on this .
could you also provide your handleStyleLoad
method?
handleStyleLoad = map => {
map.resize();
};
I've sent you the whole component in your email registered at github.
Thanks! I'll take a look.
@mklopets, did you have any progress with it? if not, can you or @jvskriubakken send it to me as well?
I ran into the same issue (similar stack strace with layer-events-hoc.js:263 Uncaught TypeError: Cannot read property 'on' of undefined
appearing after upgrading from 3.9.2 to 4+) and this seems to be related to #691. To check that my issue was related to #691, I used MapContext.Consumer
in the crashing Map
component and the value provided was always undefined
.
Then I checked all my imports from react-mapbox-gl
throughout my project and I realised that some were using paths like react-mapbox-gl/lib/Marker
.
After fixing them to use only from 'react-mapbox-gl'
, The MapContext.Consumer provided the map as expected and no more undefined
were logged.
This has also fixed the runtime error.
Please help!
We where planning to release at the end of this week and suddenly our application using react-mapbox-gl fail s Stacktrace:
package.json
The error suddenly occurred in our product without we had done any changes to our map component using react-mapbox-gl or the data given to it. So we suspect it could be an issue with an indirect dependency, which proved a bug? in EnhancedLayer component?