Skip to content

Custom draw control component works on local instance but not after build and deployment (React) #13486

Open
@lymine1996

Description

@lymine1996

I have a custom draw control here:

import React, { useCallback } from "react";
import mapboxgl from "mapbox-gl";
import MapboxDraw from "@mapbox/mapbox-gl-draw";
import { useControl } from "react-map-gl";
import CheapRuler from "cheap-ruler";
import * as turf from "@turf/turf";
import "@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css";
import "mapbox-gl/dist/mapbox-gl.css";

const DrawControl = (props) => {
  const {
    onCreate = () => {},
    onUpdate = () => {},
    onDelete = () => {},
    position = "top-right",
  } = props;

  const handleRender = useCallback(({ target: map }) => {
    if (!map) return;

    let labelFeatures = [];
    const drawControl = map._controls.find(
      (control) => control instanceof MapboxDraw
    );
    if (!drawControl) return;

    const all = drawControl.getAll();
    const ruler = new CheapRuler(map.getCenter().lat, "meters");

    if (all && all.features) {
      all.features.forEach((feature) => {
        switch (turf.getType(feature)) {
          case "Point":
            if (feature.geometry.coordinates.length > 0) {
              const label = `${feature.geometry.coordinates[1].toFixed(
                4
              )}, ${feature.geometry.coordinates[0].toFixed(4)}`;
              labelFeatures.push(
                turf.point(feature.geometry.coordinates, {
                  type: "point",
                  label,
                })
              );
            }
            break;

          case "LineString":
            if (feature.geometry.coordinates.length > 0) {
              const length = ruler.lineDistance(feature.geometry.coordinates);
              const midpoint = ruler.along(
                feature.geometry.coordinates,
                length / 2
              );
              const label = `${Math.round(length)} m`;
              labelFeatures.push(turf.point(midpoint, { type: "line", label }));
            }
            break;

          case "Polygon":
            if (
              feature.geometry.coordinates.length > 0 &&
              feature.geometry.coordinates[0].length > 3
            ) {
              const area = turf.area(feature);
              const centroid = turf.centroid(feature).geometry.coordinates;
              const label = `${(area * 0.000247105).toFixed(2)} acres`; // Convert to acres
              labelFeatures.push(turf.point(centroid, { type: "area", label }));
            }
            break;
        }
      });
    }

    if (map.getSource("measurements-source")) {
      map.getSource("measurements-source").setData({
        type: "FeatureCollection",
        features: labelFeatures,
      });
    } else {
      map.addSource("measurements-source", {
        type: "geojson",
        data: {
          type: "FeatureCollection",
          features: labelFeatures,
        },
      });

      map.addLayer({
        id: "measurements-layer",
        type: "symbol",
        source: "measurements-source",
        layout: {
          "text-field": ["get", "label"],
          "text-size": 14,
          "text-anchor": "center",
          "text-offset": [0, 1.2],
          "text-allow-overlap": true,
        },
        paint: {
          "text-color": "#ff0000",
        },
      });
    }
  }, []);

  useControl(
    () => new MapboxDraw({ ...props }), 
    ({ map }) => {
      map.on("draw.create", onCreate);
      map.on("draw.update", onUpdate);
      map.on("draw.delete", onDelete);
      map.on("draw.render", handleRender);

      return () => {
        map.off("draw.create", onCreate);
        map.off("draw.update", onUpdate);
        map.off("draw.delete", onDelete);
        map.off("draw.render", handleRender);
      };
    },
    { position }
  );

  return null;
};

export default DrawControl;

In the Map.jsx component:

{drawingMode && (
  <DrawControl
    displayControlsDefault={false}
    controls={{
      polygon: "true",
      trash: "true",
    }}
    defaultMode="draw_polygon"
    onCreate={onUpdate}
    onUpdate={onUpdate}
    onDelete={onDelete}
  />
)}

It works totally fine on local instance but once a build is created and deployed on Linux server, the onCreate, onUpdate, onDelete events are not captured on the user interface.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions