I'm playing around with Gatsby/Contentful and Google Maps.
I've created this component:
import React from 'react'
import { GoogleMap, Marker, InfoWindow } from 'react-google-maps'
const Map = (props) => {
return (
<GoogleMap
defaultZoom={12}
defaultCenter={{
lat: 34.0522,
lng: 118.2437
}}
>
<Marker
onMouseOver={() => {
setInfoWindow(true)
}}
onClick={() => props.setmodal(true)}
position={{
lat: 34.0522,
lng: 118.2437
}}
/>
</GoogleMap>
)
}
export default Map;
The map is showing and everything works fine. I've tried to access my Contentful data using this approach, but getting an error that allContentfulLocations are undefined. How can I query my Contentful data inside Google Maps?
Here was my approach which is failing.
import React from 'react'
import { GoogleMap, Marker, InfoWindow } from 'react-google-maps'
import { graphql } from "gatsby"
export const query = graphql`
{
allContentfulLocations {
nodes {
id
name
location {
lat
lon
}
}
}
}
`
const Map = ({props, data}) => {
const {
allContentfulLocations: { nodes: locations },
} = data
const [infoWindow, setInfoWindow] = useState(false)
return (
<GoogleMap
defaultZoom={12}
defaultCenter={{
lat: location.location.lat
lng: location.location.lon
}}
>
{locations.map(location => {
return (
<Marker
onMouseOver={() => {
setInfoWindow(true)
}}
onClick={() => props.setmodal(true)}
position={{
lat: 34.0522,
lng: 118.2437
}}
/>
)
})}
</GoogleMap>
)
}
export default Map;
Use:
import React from 'react'
import { GoogleMap, Marker, InfoWindow } from 'react-google-maps'
import { useStaticQuery, graphql } from "gatsby"
const Map = (props) => {
const data = useStaticQuery(graphql`
{
allContentfulLocations {
nodes {
id
name
location {
lat
lon
}
}
}
}
`)
const {
allContentfulLocations: { nodes: locations },
} = data
const [infoWindow, setInfoWindow] = useState(false)
return (
<GoogleMap
defaultZoom={12}
defaultCenter={{
lat: location.location.lat
lng: location.location.lon
}}
>
{locations.map(({location}) => {
console.log(location);
return (
<Marker
onMouseOver={() => {
setInfoWindow(true)
}}
onClick={() => props.setmodal(true)}
position={{
lat: 34.0522,
lng: 118.2437
}}
/>
)
})}
</GoogleMap>
)
}
export default Map;
If your component (Map
) is not a page, you won't be able to use page queries and therefore you will be forced to use a static query
Notice the destructuring in the map
loop:
locations.map(({location}) =>
In the way you were using the loop, location
was the iterable variable, not the location
object itself. You should access to location.location
in your approach, you're avoiding that repetition, using a destructuring in the same declaration on the iterable object as I provided. I've also added a console.log()
for debugging purposes, take a look at what's inside in both approaches.
In addition, if you look at your code:
const Map = ({props, data}) => {
You are destructuring props
as props
itself so. I've removed that destructuring and I've added it to:
const {
allContentfulLocations: { nodes: locations },
} = props.data