0

I have a the following layer:

class DataLayer extends Component {
  static contextTypes = {
    map: PropTypes.object, // Leaflet map
  };

  componentDidMount() {
    const { client } = this.props;

    // Craete source, styles and layer with the given props
    const cartoSource = new carto.source.Dataset('dataset');
    const cartoCSS = new carto.style.CartoCSS(style);
    const layer = new carto.layer.Layer(cartoSource, cartoCSS);

    // Add them to the client and to the map
    client.addLayer(layer);
    client.getLeafletLayer().addTo(this.context.map);
  }


  // ... missing methods to handle styles/source updates


  render() {
    return null; // No need to render anything :)
  }
}

export default DataLayer;

Then, I have the following component that shows the Layer component:

class Canvas extends Component {
  state = {
    center: [40.6552398976147, -73.959729361534119],
    zoom: 11,
    checked: false
  };

  constructor(props) {
    super(props);

    // Setup the client in the contructor with our user and apiKey
    this.cartoClient = new carto.Client({
      apiKey: "APIKEY",
      username: "LOGIN"
    });
  }

  onClick(e) {
    this.setState({
      checked: !this.state.checked
    });

  }

  render() {
    const { center, zoom } = this.state;

    return (
      <div>
        <div>
          <label className="switch">
                  <input
                    type="checkbox"
                    onClick={this.onCheck.bind(this)}
                    checked={this.state.checked}
                  />
                  <span className="slider" />
                </label>
        </div>
        <div>
          <Map center={center} zoom={zoom}>

            <Basemap attribution="" url={CARTO_BASEMAP}/>


            {this.state.checked ? <DataLayer client={this.cartoClient}/> : null}
          </Map>
        </div>
      </div>
    )
}
export default Canvas;  

Everything works great for the first try, when the checkbox triggers checked to be true and the DataLayer component mounts. However, when I uncheck the checkbox and expect the DataLayer component to be unmount, it doesn't. I believe the reason is a missing method to handle it in the DataLayer component once it's been updated.

How to make DataLayer component to "unmount" when the toggle is set to false?

0

In componentWillUnmount you can call client.removeLayer.

Take into account that the element where Leaflet draws is not unmounted (I guess Leaflet is managed in the Map component) so the tiles of the layer have already been drawn. Call removeLayer to be sure that it's correctly refreshed with no content from that layer.

https://carto.com/developers/carto-js/reference/#cartoclientremovelayer

  • I tried adding client.removeLayer() to componentWillUnmount(), and I toggle the component by either showing it (if checkbox is true) or hiding (: null) in the parent React component. But again, once rendered, it stays there :/ Could you please add a detailed example in your answer? – Ruham Jul 22 '18 at 21:59
  • codesandbox.io/s/mqm0j22o38 My structure of layers is based according to this. – Ruham Jul 22 '18 at 22:07
  • codesandbox.io/s/nkno85woo4 Here you go. The point is that client.removeLayer needs the layer as an argument. If you keep the reference to the layer, you pass it to the function and everything will work as expected. – Ivan Malagon Jul 23 '18 at 8:30
0

Carto's client.removeLayer(layerName) doesn't work, so apparently I had to come up with this solution:

componentWillUnmount() {
    const { client } = this.props;
    let array;
    array = client.getLayers();

    const indexedById = array.reduce((a, { _id }, i) => {
      a[_id] = i;
      return a;
    }, {});
    let layerId;
    layerId = indexedById.LAYERNAME;

    client.removeLayer(array[layerId])
  }

Where LAYERNAME is the id of the layer once created:

const LAYERNAME= new carto.layer.Layer(cartoSource, cartoCSS, {id: "LAYERNAME"});
  • This in unnecessary if you keep the reference to the layer, that I guess you can do with no problem in your example. You can check it working here codesandbox.io/s/nkno85woo4 – Ivan Malagon Jul 23 '18 at 8:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.