mapbox-gl-js icon indicating copy to clipboard operation
mapbox-gl-js copied to clipboard

flyTo method throws me undefined

Open StianOek opened this issue 2 years ago • 3 comments

mapbox-gl-js version:

Question

Hey!

I'm using the useMap hook from the "react-map-gl": "^7.0.10"

and i invoke the function like in the docs description : const { current: map } = useMap();

With the code below i get the "Uncaught TypeError: Cannot read properties of undefined (reading 'flyTo')"

const handleLocations = (item) => {
    // eslint-disable-next-line react-hooks/rules-of-hooks

    map.flyTo({ center: [52, 32] });

    console.log(item[1], item[0]);
  };
  
   onClick={() => handleLocations(data[item].coords)}
  

I cant seem to work this out.

Fingers crossed for that someone see this :)

Links to related documentation

StianOek avatar Apr 24 '22 16:04 StianOek

Thanks for reporting this. Could you please share a fully example that reproduces this?

ansis avatar May 02 '22 15:05 ansis

Sure.

This is the full component. I hope i'm close though, but im not sure if im doing the setup right

import React, { useState, useEffect, useRef } from "react";

import MapBox, { Marker, Popup, useMap } from "react-map-gl";
import { useLoading, fetchJSON } from "../../helpers/useFetch";
import { HiLocationMarker } from "react-icons/hi";
import mapboxgl from "mapbox-gl";
import { MdKeyboardArrowRight } from "react-icons/md";
import styled from "styled-components";
import zeiptLogo from "../../assets/img/zeiptLogoOnly.svg";
import { MAPBOX_TOKEN_KEY } from "../../helpers/constants";

const Map = () => {
  const { current: map } = useMap();

  const { loading, error, data } = useLoading(
    async () => await fetchJSON(API_STRING)
  );
  console.log(data);
  const [showPopup, setShowPopup] = useState(false);
  const [changeViewport, setChangeViewport] = useState();
  const [viewport, setViewport] = useState({
    latitude: 59.913868,
    longitude: 10.752245,
    zoom: 4,
  });

  const handleLocations = (item) => {
    map.flyTo({ center: [83, 23] });
    console.log(item[1], item[0]);
  };

  if (!data) {
    return "";
  }
  if (error) {
    return <p>Error: {error.toString()}</p>;
  }

  return (
    <Container>
      <SubContainer>
        <div
          style={{
            width: "100%",
            padding: "0.5rem",
          }}
        >
          <div
            style={{
              display: "flex",
              padding: "1rem",
            }}
          >
            <img src={zeiptLogo} alt="company logo" />
            <Title>Enabled store locations</Title>
          </div>

          <div>
            <Button>Oslo</Button>
            <Button>Trondheim</Button>
            <Button>Bergen</Button>
            <Button>Vis alle</Button>
          </div>
          <Input>
            <input type="text" />
          </Input>
          <Scroll>
            {Object.keys(data)
              .filter((value) => data[value])
              .map((item) => {
                return (
                  <>
                    <StoreNames
                      onClick={() => handleLocations(data[item].coords)}
                    >
                      <h4>{data[item].store_name}</h4>
                      <MdKeyboardArrowRight size={20} />
                    </StoreNames>
                  </>
                );
              })}
          </Scroll>
        </div>
        <MapBox
          mapboxAccessToken={MAPBOX_TOKEN_KEY}
          initialViewState={viewport}
          style={{ width: "100%", height: "100%" }}
          mapStyle="mapbox://styles/mapbox/streets-v8"
          movi
        >
          {Object.keys(data)
            .filter((value) => data[value])
            .map((item) => {
              return (
                <>
                  <Marker
                    longitude={data[item].coords[0]}
                    latitude={data[item].coords[1]}
                    anchor="bottom"
                  >
                    <HiLocationMarker size={35} color="#00519a" />
                  </Marker>
                  {showPopup && (
                    <Popup
                      longitude={data[item].coords[0]}
                      latitude={data[item].coords[1]}
                      anchor="bottom"
                      onClose={() => setShowPopup(false)}
                    >
                      You are here
                    </Popup>
                  )}
                </>
              );
            })}
        </MapBox>
      </SubContainer>
    </Container>
  );
};

export default Map;

StianOek avatar May 02 '22 15:05 StianOek

I'm seeing something similar. If I specify id= on my Map like <Map id="whatever" /> AND I use a <MapProvider> then I eventually see the hook yield some meaningful data.

useMap: {whatever: {…}, current: undefined}

current seems to be always undefined with or without an id and with or without the provider

williamhaley avatar Jul 22 '22 19:07 williamhaley

Having the same problem. useMap().current is always undefined.

I've created a minimal reproduction example. It uses react-map-gl – so I guess the bug could also be on their side? Not sure how to diagnose whether this is a problem with mapbox-gl or react-map-gl

https://stackblitz.com/edit/react-ts-w4lkhv?file=MyMap.tsx

pReya avatar Jan 29 '23 19:01 pReya

Hi all,

I assume that the useMap().current might be undefined in the first render until the map load event is emitted.

Most likely, this is the issue with the react-map-gl wrapper itself. So this issue should belong to the https://github.com/visgl/react-map-gl bug tracker. Feel free to reopen this issue if you have any questions.

stepankuzmin avatar Jan 30 '23 14:01 stepankuzmin