CartoDB / carto-react-template

CARTO for React. The best way to develop Location Intelligence (LI) Apps usign CARTO platform and React
https://sample-app-react.carto.com
MIT License
39 stars 26 forks source link

How I could add layer to map dynamically #286

Closed LongJohnSilver1504 closed 3 years ago

LongJohnSilver1504 commented 3 years ago

Hello I recieve the layers info from An API and I need to render layers dynamically. How I could do this? Thanks

borja-munoz commented 3 years ago

Hi!

There are many options to achieve this. For instance, you can call your API in a useEffect hook to retrieve the data, store it in the global (Redux) or component state and then use it in the data parameter when you instantiate the layer.

LongJohnSilver1504 commented 3 years ago

Hi @borja-munoz, thanks for your response. Using carto-react I could make my api call and pass the layer and the source to redux using the corresponding actions. The problem is When I try to iterate over function for create the layers passed to DeckGL map. For example here: https://github.com/CartoDB/carto-react-telco-demo We create all layers statically and pass this layers to the map with the function getlayers()

export const getLayers = () => {
  return [
    GeocoderLayer(),
    CellTowersLayer(),
    PopulationLayer(),
    InternetSpeedsLayer(),
    SummaryHexLayer(),
    MarketCoverageLayer(),
    PotentialRevenueLayer(),
    SociodemographicsLayer(),
    // Auto import layers
  ];
};

that work perfect but if I create a "component" CreateLayer like

import { useSelector } from 'react-redux';
import { CartoSQLLayer } from '@deck.gl/carto';
import { selectSourceById, selectOAuthCredentials } from '@carto/react-redux';
import { useCartoLayerProps } from '@carto/react-api';

export default function CreateLayer({layer}) {
const layers = useSelector((state) => state.carto.layers);
  const source = useSelector((state) => selectSourceById(state, layers[layer.id]?.source));
  const cartoLayerProps = useCartoLayerProps(source);

  if (layer&& source) {
    return new CartoSQLLayer({
      ...cartoFilterProps,
      id: OPEN_CELL_ID_LAYER_ID,
      data: source.data,
      credentials,
      getLineColor: hexToRgb(layer.color, layer.opacity + 0.1),
      getFillColor: hexToRgb(layer.color, layer.opacity),
      pointRadiusUnits: 'pixels',
      pointRadiusMinPixels: 5,
      pickable: true,

      onHover: (info) => {
        if (info?.object) {
          info.object = {
            html: renderCellTowersTooltip(info.object),
            style: {},
          };
        }
      },
    });
  }
}

In some previous step I add the layers and the sources to redux and make something like

const getLayers = () => layers.map(layer => CreateLayer(layer))

it doesn't work.

Thanks

borja-munoz commented 3 years ago

Hi, you have closed the issue so I'm not sure if you still have the problem. It is difficult to know what's happening without looking at the full source code.

LongJohnSilver1504 commented 3 years ago

Sorry, I close the issue by mistake. @borja-munoz . this is my email could you write me, I would really glad to meet you dahermora91@gmail.com Muchas gracias