🏠 back to Observable

Update marker in map cell without cell refresh

Hi folks! Question on reacting to data changes without refreshing the entire cell.

In my case, I have a map, and on that map I have a marker. If I want the marker’s position to be updated with the value of another cell, the entire map redraws when the value changes.

here’s the notebook

Is it possible to have the map cell respond to the updated value without re-evaluating the entire cell?

1 Like

To invert a recent meme: well, no but kind of yes.

Basically: no, you cannot partially re-evaluate a cell. Therefore, the solution is to split out the cell into more fine-grained little cells, so that the parts of the cell that you don’t want to re-evaluate don’t do so. It’s basically just good old refactoring, but with Observable cells!

In your example, the cell in question

  • creates a mapbox object
  • creates a marker object and adds it to the mapbox object
  • sets the marker object to the value of the longitude cell

What you basically are saying is that you only want to re-evaluate the last step when the longitude cell updates. So we need to split this cell into three cells: one for each described step. Then only the last cell will depend on longitude, meaning the other two won’t re-evaluate. Which was essentially what you were going for, right?

viewof map = {
  const container = html`<div style="height:400px;">`;
  yield container; // Give the container dimensions.
  const map = container.value = new mapboxgl.Map({
    container,
    center: [0,0],
    zoom: 1,
    style: mapStyle(),
    scrollZoom: false
  });
  
  invalidation.then(() => map.remove());
}
marker = {
  const marker = new mapboxgl.Marker()
    .setLngLat([0, 0])
    .addTo(map);
  // make sure we clean up the marker if we re-run this cell too!
  invalidation.then(() => marker.remove());
  return marker;
}
// make only this call depend on changes to `longitude` cell
marker.setLngLat([longitude, 0])
2 Likes

Awesome. Makes perfect sense!