I am trying to use mapbox-gl with magento2 which uses requireJS. Mapbox-js seems to load but I have got a js error. I don't know if I missed requirejs config or if the error is due to my js code or if it's a bug ?
If someone can help me, thanks you.
mapbox-gl-js version: v1.0.0, v1.2.0 and v1.3.0
browser: Chrome
Steps to Trigger Behavior 1.Try to use mapbox into magento2 with requireJs 2. 3.
Link to Demonstration No demonstration available sorry.
Expected Behavior No error
Actual Behavior Error in broswer console : mapbox-gl-3.js:635 Uncaught TypeError: self.XMLHttpRequest is not a constructor at mapbox-gl-3.js:635 at dt (mapbox-gl-3.js:654) at Object.mt [as getArrayBuffer] (mapbox-gl-3.js:656) at Function.v.loadGlyphRange (mapbox-gl-3.js:11511) at mapbox-gl-3.js:11474 at mapbox-gl-3.js:9863 at Array.forEach () at Object.t.asyncAll (mapbox-gl-3.js:9862) at v.getGlyphs (mapbox-gl-3.js:11466) at i.getGlyphs (mapbox-gl-3.js:14227) (anonymous) @ mapbox-gl-3.js:635 dt @ mapbox-gl-3.js:654 mt @ mapbox-gl-3.js:656 v.loadGlyphRange @ mapbox-gl-3.js:11511 (anonymous) @ mapbox-gl-3.js:11474 (anonymous) @ mapbox-gl-3.js:9863 t.asyncAll @ mapbox-gl-3.js:9862 v.getGlyphs @ mapbox-gl-3.js:11466 i.getGlyphs @ mapbox-gl-3.js:14227 du.receive @ mapbox-gl-3.js:8739
At this moment, this is undefined, I guess it shouldn't but i don 't know how to fix it.
requirejs-config:
var config = { deps: [ [...] ], map: { '*': { [...] mapboxgl: "js/mapbox-gl-3", MapboxGeocoder: "js/mapbox-gl-geocoder.min", turf: "js/turf.min" } }, paths: { [...] }, config: { mixins: { [...] } }, shim : { 'mapbox-gl': { exports: 'mapbox-gl' }, 'leaflet-mapbox-gl': { deps: ['leaflet','mapbox-gl'] } } };
script JS :
`
require(['mapboxgl', 'MapboxGeocoder', 'turf'], function (mapboxgl, MapboxGeocoder, turf) {
// This will let you use the .remove() function later on
if (!('remove' in Element.prototype)) {
Element.prototype.remove = function () {
if (this.parentNode) {
this.parentNode.removeChild(this);
}
};
}
console.log('vahir2');
mapboxgl.accessToken = 'my_token_here';
// This adds the map
var map = new mapboxgl.Map({
// container id specified in the HTML
container: 'map',
// style URL
style: 'mapbox://styles/mapbox/streets-v9?optimize=true',
// initial position in [long, lat] format
center: [6.8541548, 46.4564862],
// initial zoom
zoom: 5,
scrollZoom: true
});
console.log('vahir3');
map.addControl(new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true,
showUserLocation: true
}));
map.addControl(new mapboxgl.NavigationControl());
//geocoder
var geocoder = new MapboxGeocoder({
accessToken: mapboxgl.accessToken, // Set the access token
mapboxgl: mapboxgl, // Set the mapbox-gl instance
marker: false, // Do not use the default marker style
bbox: [-5.7616150379, 41.9409963458, 19.6387755871, 55.208571099]
});
map.addControl(geocoder, 'top-left');
// This adds the data to the map
map.on('load', function (e) {
map.addSource('single-point', {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: [] // Notice that initially there are no features
}
});
map.addLayer({
id: 'point',
source: 'single-point',
type: 'circle',
paint: {
'circle-radius': 10,
'circle-color': '#007cbf',
'circle-stroke-width': 3,
'circle-stroke-color': '#fff'
}
});
geocoder.on('result', function (ev) {
var searchResult = ev.result.geometry;
map.getSource('single-point').setData(searchResult);
var options = {units: 'kilometers'};
stores.features.forEach(function (store) {
Object.defineProperty(store.properties, 'distance', {
value: turf.distance(searchResult, store.geometry, options),
writable: true,
enumerable: true,
configurable: true
});
});
stores.features.sort(function (a, b) {
if (a.properties.distance > b.properties.distance) {
return 1;
}
if (a.properties.distance < b.properties.distance) {
return -1;
}
// a must be equal to b
return 0;
});
var listings = document.getElementById('listings');
while (listings.firstChild) {
listings.removeChild(listings.firstChild);
}
buildLocationList(stores);
function sortLonLat(storeIdentifier) {
var lats = [stores.features[storeIdentifier].geometry.coordinates[1], searchResult.coordinates[1]];
var lons = [stores.features[storeIdentifier].geometry.coordinates[0], searchResult.coordinates[0]];
var sortedLons = lons.sort(function (a, b) {
if (a > b) {
return 1;
}
if (a.distance < b.distance) {
return -1;
}
return 0;
});
var sortedLats = lats.sort(function (a, b) {
if (a > b) {
return 1;
}
if (a.distance < b.distance) {
return -1;
}
return 0;
});
map.fitBounds([
[sortedLons[0], sortedLats[0]],
[sortedLons[1], sortedLats[1]]
], {
padding: 100
});
}
sortLonLat(0);
createPopUp(stores.features[0]);
});
// This is where your '.addLayer()' used to be, instead add only the source without styling a layer
map.addSource("places", {
"type": "geojson",
"data": stores,
tolerance: 3
});
// Initialize the list
buildLocationList(stores);
});
// This is where your interactions with the symbol layer used to be
// Now you have interactions with DOM markers instead
stores.features.forEach(function (marker, i) {
// Create an img element for the marker
var el = document.createElement('div');
el.id = "marker-" + i;
el.className = 'marker';
// Add markers to the map at all points
new mapboxgl.Marker(el, {
offset: [0, -23]
})
.setLngLat(marker.geometry.coordinates)
.addTo(map);
el.addEventListener('click', function (e) {
// 1. Fly to the point
flyToStore(marker);
// 2. Close all other popups and display popup for clicked store
createPopUp(marker);
// 3. Highlight listing in sidebar (and remove highlight for all other listings)
var activeItem = document.getElementsByClassName('active');
e.stopPropagation();
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
var listing = document.getElementById('listing-' + i);
listing.classList.add('active');
});
});
function flyToStore(currentFeature) {
map.flyTo({
center: currentFeature.geometry.coordinates,
zoom: 15
});
}
function createPopUp(currentFeature) {
var popUps = document.getElementsByClassName('mapboxgl-popup');
if (popUps[0]) popUps[0].remove();
var popup = new mapboxgl.Popup({
closeOnClick: false
})
.setLngLat(currentFeature.geometry.coordinates)
.setHTML('<h3>' + currentFeature.properties.name + '</h3>' +
'<h4>' + currentFeature.properties.desc + '</h4><img style="padding: 0% 0% 5% 6%;" src="/media/wysiwyg/store-locator/' + currentFeature.properties.image + '" />')
.addTo(map);
}
function buildLocationList(data) {
for (i = 0; i < data.features.length; i++) {
var currentFeature = data.features[i];
var prop = currentFeature.properties;
var listings = document.getElementById('listings');
var listing = listings.appendChild(document.createElement('div'));
listing.className = 'item';
listing.id = "listing-" + i;
if (prop.capsules == 1) {
var icon = listing.appendChild(document.createElement('img'));
icon.src = '/media/wysiwyg/store-locator/icon_capsule.png';
icon.style = 'float: right; height:18px;';
}
if (prop.machines == 1) {
var icon = listing.appendChild(document.createElement('img'));
icon.src = '/media/wysiwyg/store-locator/icon_machine.png';
icon.style = 'float: right; height:18px;';
}
var link = listing.appendChild(document.createElement('a'));
link.href = '#';
link.className = 'title';
link.dataPosition = i;
link.innerHTML = prop.name;
var details = listing.appendChild(document.createElement('div'));
details.innerHTML = prop.desc;
if (prop.distance) {
var roundedDistance = Math.round(prop.distance * 100) / 100;
details.innerHTML += '<p><strong>Distance : ' + roundedDistance + ' km</strong></p>';
}
link.addEventListener('click', function (e) {
// Update the currentFeature to the store associated with the clicked link
var clickedListing = data.features[this.dataPosition];
// 1. Fly to the point
flyToStore(clickedListing);
// 2. Close all other popups and display popup for clicked store
createPopUp(clickedListing);
// 3. Highlight listing in sidebar (and remove highlight for all other listings)
var activeItem = document.getElementsByClassName('active');
if (activeItem[0]) {
activeItem[0].classList.remove('active');
}
this.parentNode.classList.add('active');
});
}
}
}); `