5

I am trying to create a React app that uses deck.gl on a Mapbox map, and I am having trouble updating the "data" prop within a deck.gl Scatterplot layer. I left out some code where I am returning elements, etc. I am initializing the data props as empty arrays, then using a useEffect hook to get the data from the database, but the layers' data does not update.

My guess is that this is because I am using state variable lists in my deck.gl layers as the data props.

  1. When I check the states of an array in the inspector, I see that the "data" props are still empty arrays
  2. When I check the states of the arrays the layers are tied to, I see they are no longer empty. Thus, the arrays I used in the layers' props != the arrays I have in state after I get data from Axios.

Is there an update method I need to run on the deck.gl layers?

I have also tried to pull the data in using a promise directly on initializing the layer to no avail.

Thanks so much in advance....

import React, { useContext, useEffect, useState } from "react";
import ReactMapGL from "react-map-gl";
import { DeckGL, MapController, ScatterplotLayer } from "deck.gl";
import { UserContext } from "../contexts/UserContext";
import { Dropdown, Image, SplitButton } from "react-bootstrap";
import soleTele from "../images/circle.png";
import solePower from "../images/cross.png";
import jointPole from "../images/circlecross.png";
import customer from "../images/triangle.png";
import centralOffice from "../images/CO.png";
import axios from "axios";

const libraries = ["places"];
const MAPBOX_ACCESS_TOKEN =
  "pk.eyJ1IjoianJkdXJhbnQiLCJhIjoiY2tpczNsbzIxMHVtOTMwbHIxdGRpbTJjeSJ9.BBH2615udf6dhFsXcwXFjQ";

const mapContainerStyle = {
  width: "100%",
  height: "100%",
};

const INITIAL_VIEW_STATE = {
  longitude: -122.41669,
  latitude: 37.7853,
  zoom: 10,
  pitch: 5,
  bearing: 0,
};

const data = [{ position: [-122.45, 37.78], message: "Hover over me" }];

export default function HomeMap() {
  const [hoverInfo, setHoverInfo] = useState();
  const [user, setUser] = useContext(UserContext);
  const [mode, setMode] = useState("Telephone Pole");
  const [soleTeles, setsoleTeles] = useState([]);
  const [solePowers, setsolePowers] = useState([]);
  const [jointPoles, setjointPoles] = useState([]);
  const [COs, setCOs] = useState([]);
  const [customers, setcustomers] = useState([]);
  const [viewport, setViewport] = useState({
    latitude: 32.7555,
    longitude: -97.3308,
    zoom: 10,
    width: "100%",
    height: "100%",
  });

  const request = {
    networkID: user.networkID,
  };

  const [demoLayer, setdemoLayer] = useState(
    new ScatterplotLayer({
      id: "demo",
      data,
      getPosition: (d) => d.position,
      getRadius: 1000,
      getFillColor: [255, 0, 0],
      // Enable picking
      pickable: true,
      visible: true,
      // Update app state
      onHover: (info) => setHoverInfo(info),
      // onClick: (event) => console.log("HELP"), WORKS
    })
  );

  const [soleTeleLayer, setsoleTeleLayer] = useState(
    new ScatterplotLayer({
      id: "soleTele",
      data: soleTeles,
      getPosition: (d) => [d.long, d.lat],
      getRadius: 1000,
      visible: true,
      getFillColor: [255, 0, 0],
      // Enable picking
      pickable: true,
      // Update app state
      onHover: (info) => setHoverInfo(info),
      // onClick: (event) => console.log("HELP"), WORKS
    })
  );

OTHER LAYERS LEFT OUT...

  useEffect(() => {
    // Update the document title using the browser API
    axios
      .post("http://localhost:5000/poles/network", request)
      .then((res) => {
        console.log(res.data);
        res.data.forEach((pole) => {
          const newPole = {
            type: pole.type,
            id: pole._id,
            position: [pole.long, pole.lat],
          };
          console.log(newPole);
          if (pole.type === "Telephone Pole") {
            setsoleTeles((oldArray) => [...oldArray, newPole]);
          } else if (pole.type === "Power Pole") {
            setsolePowers([...solePowers, newPole]);
          } else if (pole.type === "Central Office") {
            setCOs([...COs, newPole]);
          } else if (pole.type === "Customer") {
            setcustomers([...customers, newPole]);
          } else if (pole.type === "Joint Pole") {
            setjointPoles([...jointPoles, newPole]);
          }
        });
        soleTeleLayer._finalize();
      })
      .catch((err) => console.log(err));
  }, []);

  const layers = [
    demoLayer,
    soleTeleLayer,
    // solePowerLayer,
    // jointLayer,
    // centralOfficeLayer,
    // customerLayer,
  ];


  • 3
    For anyone who sees this, I found a solution: for some reason, wrapping the creation of layers in a useEffect hook did it. Thus, I initialized the data set prior to adding in the layers. Adding additional data to those arrays after the fact also automatically updates the layers. – Julian Durantini Dec 21 '20 at 19:52

0 Answers0