I followed this recommendation from the Leaflet Routing Machine regarding interactions i.e. onClicks.
With my implementation, I'm saving the waypoints in local-storage—saving the latitude and longitude obj I get from the map click, to an array called markers
The event handler has a conditional which separates the click into two outcomes—an adding (to the markers array) or updating it.
Like I said in the title, initial interaction is fine, it's just when I remove any marker and try to add it again is the problem. Also I noticed the markers
array is completely empty, and next event fired is an update when clearly it should be an addition:
Here is the relevant code in the Routing Machine:
class Routing extends MapLayer {
static contextType = UserContextDispatch;
constructor(props) {
super(props);
this.state = {
showSpinner: false,
localDispatch: null,
};
this.handleLoader = this.handleLoader.bind(this);
this.handleRemoveWayPoint = this.handleRemoveWayPoint.bind(this);
this.handleSetMarker = this.handleSetMarker.bind(this);
}
handleRemoveWayPoint() {
var waypoints = this.control.getWaypoints();
for (let i = waypoints.length - 1; i >= 0; i--) {
console.log('waypoints[i].latLng !== null ', waypoints[i].latLng !== null);
if (waypoints[i].latLng !== null) {
waypoints[i].latLng = null;
break;
}
}
this.control.setWaypoints(waypoints);
}
createLeafletElement(props) {
const { map } = this.props.leaflet;
if (map && !this.control) {
this.control = L.Routing.control({
collapsible: true,
show: false,
position: 'bottomleft',
lineOptions: {
styles: [{ color: 'chartreuse', opacity: 1, weight: 5 }]
},
waypoints: [null],
createMarker: function(i, wp, nWps) {
if (i === 0) {
return L.marker(wp.latLng, {
icon: startIcon,
draggable: true,
keyboard: true,
alt: 'current location'
}).on('drag', function(e) {
e.latlng.alt = 'current location';
console.log('there be dragons start!!', e);
RoutingMachineRef.handleSetMarker({
...e.oldLatLng,
...e.latlng
});
});
}
if (i === nWps - 1) {
return L.marker(wp.latLng, {
icon: endIcon,
draggable: true,
alt: 'current destination'
}).on('drag', function(e) {
e.latlng.alt = 'current destination';
console.log('there be dragons dest!!', e);
RoutingMachineRef.handleSetMarker({
...e.oldLatLng,
...e.latlng
});
});
}
}
});
L.Routing.errorControl(this.control).addTo(map);
}
return this.control.getPlan();
}
componentDidMount() {
const { map } = this.props.leaflet;
console.log('markers ', markers);
this.setState(prevState => {
localDispatch: prevState.localDispatch = this.context.dispatch;
});
map.addControl(this.control);
}
updateLeafletElement(fromProps, toProps) {
const { map } = this.props.leaflet;
var self = this;
self;
var { markers } = this.props;
function createButton(label, container) {
var btn = L.DomUtil.create('button', '', container);
btn.setAttribute('type', 'button');
btn.innerHTML = label;
return btn;
}
var { localDispatch } = this.state;
var container = L.DomUtil.create('div'),
startBtn = createButton('Start from this location', container),
destBtn = createButton('Go to this location', container);
map.on(
'click',
function(e) {
L.popup()
.setContent(container)
.setLatLng(e.latlng)
.openOn(map);
L.DomEvent.on(startBtn, 'click', function() {
if (e.latlng) {
e.latlng.alt = 'current location';
console.log('adding);
localDispatch({
type: 'addMarker',
payload: {
marker: e.latlng
}
});
}
if (markers.length === 0) {
console.log('updating ');
e.latlng.alt = 'current location';
localDispatch({
type: 'updateMarkers',
payload: {
marker: e.latlng
}
});
}
self.control.spliceWaypoints(0, 1, e.latlng);
map.closePopup();
});
L.DomEvent.on(
destBtn,
'click',
function() {
console.log('e', e);
if (markers[1] === undefined) {
e.latlng.alt = 'current destination';
console.log('e.latlng ', e.latlng);
localDispatch({
type: 'addMarker',
payload: {
marker: e.latlng
}
});
}
if (toProps.markers[1] !== undefined) {
console.log('updating ');
e.latlng.alt = 'current destination';
localDispatch({
type: 'updateMarkers',
payload: {
marker: e.latlng
}
});
}
this.control.spliceWaypoints(1, 1, e.latlng);
map.closePopup();
}.bind(this)
);
}.bind(this)
);
if (toProps.removeRoutingMachine !== false) {
this.control.setWaypoints([]);
}
}
componentWillUnmount() {
this.destroyRouting();
}
destroyRouting() {
const { map } = this.props.leaflet;
if (map) {
map.removeControl(this.control);
}
}
}
export default withLeaflet(Routing);
Thanks in advance!
As you can see I have some code related to the
Map
(the onClick for the waypoints) in theRoutingMachine
itself; after thinking about it I moved it to theMap
component as ahandlerFunction
. And now it works!And this is the Routing Machine: