I try to add a simple route in my map but when i call google.maps.DirectionsService() i get this google is undefined, so i try to add a const variable but now the error message is Cannot read property 'maps' of undefined..
I don't know what im doing wrong
const google = window.google;
class Map extends Component {
constructor(props) {
super(props);
this.state = {
latitude: 0,
longitude: 0,
nombre_de_bars: null
}
}
map() {
const [selectedBar, setSelectedBar] = useState(null);
const { nombre_de_bars } = this.state
const rows = nombre_de_bars.map(bar =>
<Marker key={bar._id}
position={{
lat: bar.latitude,
lng: bar.longitude
}}
onClick={() => {
setSelectedBar(bar);
}}
icon={{
url: '/images/biere_logo.png',
scaledSize: new window.google.maps.Size(25, 25)
}}
/>
);
return (
<GoogleMap
defaultZoom={14}
defaultCenter={{ lat: this.state.latitude, lng: this.state.longitude }}
defaultOptions={{
zoomControl: false,
mapTypeControl: false,
scaleControl: false,
streetViewControl: false,
rotateControl: false,
fullscreenControl: false
}}>
<Marker
position={{ lat: this.state.latitude, lng: this.state.longitude }}
icon={{
url: '/images/marker.png',
scaledSize: new window.google.maps.Size(50, 50)
}}
/>
{rows}
{selectedBar && (
<InfoWindow
position={{
lat: selectedBar.latitude,
lng: selectedBar.longitude
}}
onCloseClick={() => {
setSelectedBar(null);
}}
>
<div>
<p>{selectedBar.name}</p>
<p>{selectedBar.description}</p>
<button onClick={() => {
this.itineraireTo(selectedBar);
}}>Je m'y rend</button>
</div>
</InfoWindow>
)}
</GoogleMap>
);
}
render() {
const WrappedMap = withScriptjs(withGoogleMap(this.map.bind(this)));
const DirectionsService = new google.maps.DirectionsService();
return (
<WrappedMap
googleMapURL="https://maps.googleapis.com/maps/api/js?key=MY_KEY&v=3.exp&libraries=geometry,drawing,places"
loadingElement={<div style={{ height: `100%`, width: '100%' }} />}
containerElement={<div style={{ height: `100%`, width: '100%' }} />}
mapElement={<div style={{ height: `100%`, width: '100%' }} />}
/>
);
}
}
export default Map;
I try to export with withGoogleMap(Map) but not fix the problem.
I read the documentation on tomchentw.github.io but not the similar problem was occured
Related
passing as props here
<MyMapComponent
isMarkerShown
googleMapURL={https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places}
loadingElement={<div style={{ height: 100% }} />}
containerElement={<div style={{ height: 400px }} />}
mapElement={<div style={{ height: 100% }} />}
lat={lat}
lang={long}
/>
Map component
import React from 'react'
import { withScriptjs, withGoogleMap, GoogleMap, Marker } from "react-google-maps"
const MyMapComponent = withScriptjs(withGoogleMap((props) => {
return (
< GoogleMap
defaultZoom={5}
defaultCenter={{ lat: props.lat, lng: props.lang }}
>
{props.isMarkerShown && <Marker position={{ lat: props.;at, lng: props.lang }} />}
</GoogleMap >
)
}));
export default MyMapComponent;
I got this react-google-maps component it is working and I receive all the data from the different locations but the console gives me this error message:
Warning: Each child in a list should have a unique "key" prop.
In my component, I've added a unique key tho.. what's the problem?
I import the map component on the page simply like that <Map />.
import React from 'react'
import { GoogleMap, Marker, withGoogleMap, withScriptjs, InfoWindow } from "react-google-maps"
import { useStaticQuery, graphql } from "gatsby"
const Map = () => {
const data = useStaticQuery(graphql`
{
allContentfulHotels {
nodes {
id
title
location {
lat
lon
}
}
}
}
`)
const {
allContentfulHotels: { nodes: locations },
} = data
return (
<>
{locations.map(({ location }) => {
console.log(location);
return (
<GoogleMap
key={location.id}
defaultZoom={15}
defaultCenter={{
lat: location.lat,
lng: location.lon,
}}
>
<Marker
key={location.id}
position={{
lat: location.lat,
lng: location.lon,
}}
>
</Marker>
</GoogleMap>
)
})}
</>
)
}
const MapComponent = withScriptjs(withGoogleMap(Map));
const MyMap = () => (
<div>
<div
style={{ width: '100%' }}
>
<MapComponent
isMarkerShown
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `500px` }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</div>
</div>
)
export default MyMap
Hope someone knows what the problem is.
For Example: I am Using map function as below and set unique key..
{locations.map(({ location }, index) => {
console.log(location);
console.log(index);
return (
<GoogleMap
key={index}
defaultZoom={15}
defaultCenter={{
lat: location.lat,
lng: location.lon,
}}
Looks like you're specifying the same key for <GoogleMap /> and <Marker /> component, try setting different keys for components:
<GoogleMap
key={`map-${location.id}`}
defaultZoom={15}
defaultCenter={{
lat: location.lat,
lng: location.lon,
}}
>
<Marker
key={`marker-${location.id}`}
position={{
lat: location.lat,
lng: location.lon,
}}
>
</Marker>
</GoogleMap>
After fetching a json file from server keep getting following mistake
TypeError: Cannot read property 'map' of undefined
I understand that have problems with locationsData, which I'm fetching, but I assumed that it already has an array format due to the format of the parsed data (example, please, see below).
import React, { useState } from "react";
import {
withGoogleMap,
withScriptjs,
GoogleMap,
Marker,
InfoWindow,
} from "react-google-maps";
let locationsData;
fetch("http:///locations")
.then(function (u) {
return u.json();
})
.then(function (json) {
locationsData = json;
});
function Map() {
const [selectedLoc, setSelectedLoc] = useState(null);
return (
<div className="App">
<GoogleMap
defaultZoom={14}
defaultCenter={{ lat: 49.55848, lng: 23.312481 }}
>
{locationsData.map((loc) => (
<Marker
key={loc._id}
position={{
lat: loc.gps[0],
lng: loc.gps[1],
}}
onClick={() => {
setSelectedLoc(loc);
}}
/>
))}
{selectedLoc && (
<InfoWindow
position={{
lat: selectedLoc.gps[0],
lng: selectedLoc.gps[1],
}}
onCloseClick={() => {
setSelectedLoc(null);
}}
>
<div>
<h2>{selectedLoc.name}</h2>
</div>
</InfoWindow>
)}
</GoogleMap>
</div>
);
}
const WrappedMap = withScriptjs(withGoogleMap(Map));
export default function App() {
return (
<div style={{ width: "100vw", height: "100vh" }}>
<WrappedMap
googleMapURL={`https://maps.googleapis.com/maps/api/js?v=3.exp&libraries=geometry,drawing,places&key=000`}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `100%` }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</div>
);
}
Server data example:
[
{
"gps": [11, 11],
"_id": "1",
"name": "Name1"
},
{
"gps": [22, 22],
"_id": "2",
"name": "Name2"
}
]
You will need to use useEffect and do the fetching in there. You will also have to store the data in the state so that the component will re-render once the data are fetched.
function Map() {
const [selectedLoc, setSelectedLoc] = useState(null);
const [locationsData, setLocationsData] = useState([]);
useEffect(() => {
fetch("http:///locations")
.then(function(u) {
return u.json();
})
.then(function(json) {
setLocationsData(json);
});
}, [])
return (
<div className="App">
<GoogleMap
defaultZoom={14}
defaultCenter={{ lat: 49.55848, lng: 23.312481 }}
>
{locationsData.map((loc) => (
<Marker
key={loc._id}
position={{
lat: loc.gps[0],
lng: loc.gps[1],
}}
onClick={() => {
setSelectedLoc(loc);
}}
/>
))}
{selectedLoc && (
<InfoWindow
position={{
lat: selectedLoc.gps[0],
lng: selectedLoc.gps[1],
}}
onCloseClick={() => {
setSelectedLoc(null);
}}
>
<div>
<h2>{selectedLoc.name}</h2>
</div>
</InfoWindow>
)}
</GoogleMap>
</div>
);
}
before it gets assigned (locationsData = json;), the locationsData is undefined as you stated here in the initial declaration: let locationsData;
so undefined.map() will throw you the error, you can do this to remain a consistent behavior:
let locationsData = [];
or you can have a validation before calling the .map() function:
{Array.isArray(locationsData) && locationsData.map((loc) => (
<Marker
key={loc._id}
position={{
lat: loc.gps[0],
lng: loc.gps[1],
}}
onClick={() => {
setSelectedLoc(loc);
}}
/>
))}
As #Gabriele pointed out, the fetch operation is placed outside of the component. You can do this to ensure the results get assigned correctly and the component will render it:
function Map() {
const [selectedLoc, setSelectedLoc] = useState(null);
const [locationsData, setLocationsData] = useState([]);
useEffect(() => {
fetch("http:///locations")
.then(u => u.json())
.then(json => setLocationsData(json));
}, []); // Empty dependency, acts similar to componentDidMount
return (
<div className="App">
<GoogleMap
defaultZoom={14}
defaultCenter={{ lat: 49.55848, lng: 23.312481 }}
>
{locationsData.map((loc) => (
<Marker
key={loc._id}
position={{
lat: loc.gps[0],
lng: loc.gps[1],
}}
onClick={() => {
setSelectedLoc(loc);
}}
/>
))}
{selectedLoc && (
<InfoWindow
position={{
lat: selectedLoc.gps[0],
lng: selectedLoc.gps[1],
}}
onCloseClick={() => {
setSelectedLoc(null);
}}
>
<div>
<h2>{selectedLoc.name}</h2>
</div>
</InfoWindow>
)}
</GoogleMap>
</div>
);
}
Initialize locationData with empty array..
let locationsData= [];
Below is my coding:
const SiteGoogleMap = compose(
withProps({
googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAP_API_KEY}&v=3.exp&libraries=geometry,drawing,places`,
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />
}),
withScriptjs,
withGoogleMap
)((props) =>
<GoogleMap
defaultZoom={18}
defaultCenter={{ lat: 3.1314067, lng: 101.6285082 }}
>
{props.isMarkerShown && <Marker position={{ lat: -34.397, lng: 150.644 }} onClick={props.onMarkerClick} />}
<DrawingManager
defaultDrawingMode={google.maps.drawing.OverlayType.POLYGON}
defaultOptions={{
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.POLYGON
],
}
}}
onPolygonComplete={(value) => console.log(getPaths())}
/>
</GoogleMap>
I'm trying to get the path of the polygon drawn which will give me the coordinates of the paths. But it gives undefined on console.log. Do you guys know why?
Since onPolygonComplete event is mapped to polygoncomplete of DrawingManager class, the value parameter represents Polygon object:
onPolygonComplete={(value) => console.log(getPaths())}
^^^^^
polygon object
that could be passed into getPaths function:
onPolygonComplete={(value) => console.log(getPaths(value))}
and then the coordinates of the polygon drawn could be printed like this:
function getPaths(polygon){
var coordinates = (polygon.getPath().getArray());
console.log(coordinates);
}
Below is my code:
const SiteGoogleMap = compose(
withProps({
googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAP_API_KEY}&v=3.exp&libraries=geometry,drawing,places`,
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />
}),
withScriptjs,
withGoogleMap
)((props) =>
<GoogleMap
defaultZoom={18}
defaultCenter={{ lat: 3.1314067, lng: 101.6285082 }}
>
{props.isMarkerShown && <Marker position={{ lat: -34.397, lng: 150.644
}} onClick={props.onMarkerClick} />}
<DrawingManager
defaultDrawingMode={google.maps.drawing.OverlayType.POLYGON}
defaultOptions={{
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.POLYGON
],
}
}}
/>
<Polygon path={coordinates} />
</GoogleMap>
)
I would like to get the coordinates (polygon path) from my server. Below is what I have done to get it. It is a component:
export default class Map extends Component {
state = {
isMarkerShown: false,
coordinates: []
}
componentDidMount() {
this.fetchBoundaries()
}
render () {
const { coordinates } = this.state
return (
<SiteGoogleMap
isMarkerShown={this.state.isMarkerShown}
onMarkerClick={this.handleMarkerClick}
/>
);
}
async fetchBoundaries () {
try {
const { coordinates } = this.state
const item = await service.getBoundaries('59d850878328bd177bf50b4d')
coordinates = item.boundaries
this.setState({ coordinates })
} catch (e) {
notification.show('error', 'Unable to load successfully', 'Unable to load client successfully. Please try again later.')
}
}
}
From the fetchBoundaries() function, I am able to get my coordinates. But, it just can't pass it to <Polygon path={coordinates} /> for display.
Anyone know what went wrong?