google-map-react not loading - javascript

My Google Map gives following error:
"Oops! Something went wrong. This page didn't load Google Maps correctly. See the JavaScript console for technical details."
I use Gatsby and google-map-react package. My code:
const AnyReactComponent = ({ text }) => <div>{text}</div>;
static defaultProps = {
center: {
lat: 59.95,
lng: 30.33
},
zoom: 11
};
<div style={{ height: '50vh', width: '100%' }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "https://maps.google.com/maps?q=manhatan&t=&z=13&ie=UTF8&iwloc=&output=embed" }}
defaultCenter={this.props.center}
defaultZoom={this.props.zoom}
>
<AnyReactComponent
lat={59.955413}
lng={30.337844}
text="My Marker"
/>
</GoogleMapReact>
</div>

In bootstrapURLKeys you have to add google map api key not url.
you can get key from google console https://developers.google.com/maps/documentation/javascript/get-api-key
<GoogleMapReact
bootstrapURLKeys={{ key: /* YOUR KEY HERE */ }}
......
/>

Related

How to embed an exact place on google maps in Reactjs

I am redoing my website with Reactjs. I'm trying to embed an exact google place with reviews on the map so it would look like this (My website written with wordpress)
So far I could only display a pin with exact coordinates, and it would look like this
Is there a way to embed an exact place on the maps as the reviews are very important to be visible for my customers?
If I would copy the link with the embedded place like this
<iframe src="https://www.google.com/maps/embed?pb=!1m14!1m8!1m3!1d12063.71295670172!2d-72.388377!3d40.895389!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x46289ec3b50eabb9!2sMove%20Plus!5e0!3m2!1sen!2sus!4v1613186587593!5m2!1sen!2sus" width="600" height="450" frameborder="0" style="border:0;" allowfullscreen="" aria-hidden="false" tabindex="0"></iframe> into my function, the website would crash.
Here's my google maps component :
import React from "react";
import {
withScriptjs,
withGoogleMap,
GoogleMap,
Marker,
} from "react-google-maps";
const MapWrapper = withScriptjs(
withGoogleMap((props) => (
<GoogleMap
defaultZoom={13}
defaultCenter={{ lat: 40.895436, lng: -72.388484 }}
>
<Marker position={{ lat: 40.895436, lng: -72.388484 }} />
</GoogleMap>
))
);
function MyMap() {
return (
<>
<MapWrapper
googleMapURL="https://maps.googleapis.com/maps/api/myAPIHere"
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `100%` }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</>
);
}
export default MyMap;
The map from the screenshot you want to achieve is using Maps Embed API while the "react-google-maps" library in your code is using Maps JavaScript API. These APIs are different and if you want to achieve the one from your screenshot in Reactjs, you can put the directly inside the div that you want to display. You can generate the iframe of your place you can check this link. Just search for your place and it will generate the iframe. Please note that there's a key parameter in the iframe link. This means that you need to put an API key in your request.
Here is a sample code and code snippet below:
import React from "react";
import ReactDOM from "react-dom";
function App() {
return (
<div>
<h1>MAPS!</h1>
<p>Please see map below</p>
<iframe
width="600"
height="450"
style={{ border: 0 }}
loading="lazy"
allowfullscreen
src="https://www.google.com/maps/embed/v1/place?q=place_id:ChIJ92pXbcOV6IkRuasOtcOeKEY&key=YOUR_API_KEY"
/>
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
Here is a code below:
function initMap() {
var mapOptions, map, marker,infoWindow = '',
element = document.getElementById( 'map-canvas' );
mapOptions = {
zoom: 8,
center: new google.maps.LatLng( 0,0 ),
disableDefaultUI: false, // Disables the controls like zoom control on the map if set to true
scrollWheel: true, // If set to false disables the scrolling on the map.
draggable: true, // If set to false , you cannot move the map around.
};
map = new google.maps.Map( element, mapOptions ); // Till this like of code it loads up the map.
marker = new google.maps.Marker({
position: mapOptions.center,
map: map,
// icon: 'http://pngimages.net/sites/default/files/google-maps-png-image-70164.png',
draggable: true
});
}
window.initMap = initMap;
then call the map-search id in your render function
<div id="map-canvas" style={{height:500px, width:800px}}></div>

google-map-react populate multiple markers

I am currently trying to populate my google map with markers by using the map function. I can't seem to get anything to populate. Are there limitations that I am not understanding or am I missing something? I tried replacing FontAwesomeIcon with something more simple but it doesn't render. If you copy paste FontAwesomeIcon multiple times within the GoogleMapReact component it seems to work but I can't seem to make it work with map. Any suggestions would be much appreciated.
render() {
const {center, zoom} = this.props;
const listingPins = this.props.testList.map((listing, index) => {
console.log(listing);
if (listing.coordinates.lat === null || listing.coordinates.lng === null){
return null
} else{
return <FontAwesomeIcon icon={faHome} size={"2x"} key={index} listing={listing} lat={listing.coordinates.lat} lng={listing.coordinates.lat} />
}
});
console.log("TEST");
console.log(listingPins);
return (
<div style={{ height: '100vh', width: '100%' }}>
<GoogleMapReact
bootstrapURLKeys={{ key: "key" }}
center={center}
zoom={zoom}
>
{listingPins}
</GoogleMapReact>
</div>
);
}
To show multiple markers on map, you have to pass an array of markers to the GoogleMapReact component as a child and map over it.
return (
<div style={{ height: '100vh', width: '100%' }}>
<GoogleMapReact>
{props.listingPins.map(pin => (
<Marker
position={{ lat: pin.latitude, lng: pin.longitude }}
key={pin.id}
/>
))}
</GoogleMapReact>
</div>
);
const createMarker = ({ map, maps }: Mapprops) => {
const markers = props.listingPins.map(data => {
return new maps.Marker({ position: data });
});
};
<GoogleMapReact
bootstrapURLKeys={{ key: "key" }}
center={center}
zoom={zoom}
onGoogleApiLoaded={createMarker}
>
</GoogleMapReact>
This would create the markers for you.
You need to make sure that the data object is in following format :
data: {
lat: number
lng: number
}
I'm facing the same problem.
I followed the answers above but they don't show any markers.
import React from 'react';
import GoogleMapReact, { Marker } from 'google-map-react';
let listingPins=[
{
id: 1,
latitude: 34.052235,
longitude: -118.243683,
shelter: 'Los Angeles'
},
{
id: 2,
latitude: 36.114647,
longitude: -115.172813,
shelter: 'Las Vegas'
},
{
id: 3,
latitude: 33.753746,
longitude: -84.386330,
shelter: 'Atlanta GA'
}
]
const defaultProps = {
center: {
lat: 36.114647,
lng: -115.172813
},
zoom: 10
};
const createMarker = ({ map, maps }: Mapprops) => {
const markers = listingPins.map(data => {
return new maps.Marker({ position: {lat: data.latitude, lng: data.longitude} });
});
};
export default function MainMap() {
return (
<GoogleMapReact
bootstrapURLKeys={{ key: "" }}
center={defaultProps.center}
zoom={defaultProps.zoom}
onGoogleApiLoaded={createMarker}
>
</GoogleMapReact>
)
}

react google maps onMarkerClick event not trigger in mobile

initialCenter={{
lat: lat,
lng: lng
}}
onClick={this.onMapClicked}
zoom={zoom}>
{this.state.marker.map((data, index) => {
return (
<Marker
ref={this.onMarkerMounted}
key={index}
onClick={this.onMarkerClick}
name={data.name}
phone={data.phone}
icon={{
url: data.icon,
anchor: new this.props.google.maps.Point(20, 20),
scaledSize: new this.props.google.maps.Size(80, 80)
}}
position={{"lat": data.lat, "lng": data.lng}}/>
)
}
)}
<InfoWindow
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
onClose={this.onClose}
>
<View style={{width: 100, height: 20}}>
<Text style={{
fontWeight: '600',
fontSize: 14,
color: "#54AD58"
}}>{this.state.selectedPlace.phone}</Text>
</View>
</InfoWindow>
</Map>
In React google maps, the Marker Touch event not working in mobile view. Same function works well on Desktop View. But when i call this function for mobileview it does not works properly.
If i changed the function called this.onMarkerClick() this should call the fuction when i touch the map but this will not working properly. onMapclicked event working in mobile view and desktop view. i don't know what's the problem..

How to refer to the google map object in reactjs (not the component) to use getCenter()

I am working with google maps in reactjs, i need to pass the reference of the google map object, in order to send it in a function and further apply the functions associated with it. Basically i want to use the getCenter() method on the map object.. Refer this link: https://tomchentw.github.io/react-google-maps/
This is my map component from which i want the reference of my mapObject.
const MyMapComponent = compose(
withProps({
googleMapURL:
"https://maps.googleapis.com/maps/api/js?key=iDl-
mPD1j0K6lTEiMhs3D8axW53U&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div id="mapid" style={{ height: `100%` }} />
}),
lifecycle({
componentWillMount() {
console.log("Method called");
const refs = {}
this.setState({
bounds: null,
center: {
lat: 0, lng: 0
},
})
},
}),
withScriptjs,
withGoogleMap
)(props => (
<GoogleMap defaultZoom={15} defaultCenter={{ lat: props.lat, lng: props.lng
}} onCenterChanged={props.onChange(googlemapobjectref)}>
{props.isMarkerShown && (
<Marker position={{ lat: props.lat, lng: props.lng }} />
)}
</GoogleMap>
));
And in the App component (Parent Component) I want to use reference of the map object in the onChange() function.
class App extends Component {
constructor(props){
super(props);
this.state=
{
....
};
this.onChange = this.onChange.bind(this);
}
onChange(googlemapobjectref){
const val = googlemapobjectref.getCenter();
}
I just want to use getCenter() method in this code. If i am wrong at some point plz mention and if anything is not clear, mention that too. I will try to make it clear. Thanx in advance

How to set center using external lat, lng?

I've built an application that draws an address from a data base. I've used geocoder (https://www.npmjs.com/package/geocoder) to get the lat and lng of the address and now wish that everytime I hit a button that pulls the address, it will update the map to zoom to that address and centre. Can this be done if I'm pulling the address external to the maps component?
Here's my map component so far:
const MapWithASearchBox = compose(
withProps({
googleMapURL: "https://maps.googleapis.com/maps/api/js?key=AIzaSyDYwerCGhOnkM1sNHmSrckp8D1o9hY3mZ4&v=3.exp&libraries=geometry,drawing,places",
loadingElement: <div style={{ height: `100%` }} />,
containerElement: <div style={{ height: `400px` }} />,
mapElement: <div style={{ height: `100%` }} />,
}),
lifecycle({
componentDidMount(){
},
componentWillMount() {
const refs = {}
this.setState({
bounds: null,
center: {
lat: -35.015742, lng: 138.520858
},
markers: [],
onMapMounted: ref => {
refs.map = ref;
},
onIdle: () => {
this.setState({
center: fullPos,
})
},
onBoundsChanged: () => {
this.setState({
bounds: refs.map.getBounds(),
center: refs.map.getCenter(),
})
},
onSearchBoxMounted: ref => {
console.log("s. mounted");
refs.searchBox = ref;
},
onPlacesChanged: () => {
console.log("places changed");
console.log(refs.searchBox)
console.log(refs)
const places = refs.searchBox.getPlaces();
console.log(places);
const bounds = new google.maps.LatLngBounds();
places.forEach(place => {
if (place.geometry.viewport) {
bounds.union(place.geometry.viewport)
} else {
bounds.extend(place.geometry.location)
}
});
const nextMarkers = places.map(place => ({
position: place.geometry.location,
}));
const nextCenter = _.get(nextMarkers, '0.position', this.state.center);
this.setState({
center: nextCenter,
markers: nextMarkers,
});
// refs.map.fitBounds(bounds);
},
})
},
}),
withScriptjs,
withGoogleMap
)(props =>
<GoogleMap
ref={props.onMapMounted}
defaultZoom={20}
center={props.center}
onBoundsChanged={props.onBoundsChanged}
mapTypeId={google.maps.MapTypeId.SATELLITE}
panControl={true}
scrollwheel={false}
>
<SearchBox
ref={props.onSearchBoxMounted}
bounds={props.bounds}
controlPosition={google.maps.ControlPosition.TOP_LEFT}
onPlacesChanged={props.onPlacesChanged}
>
<input
type="text"
placeholder="Customized your placeholder"
value={fullAdd}
style={{
boxSizing: `border-box`,
border: `1px solid transparent`,
width: `240px`,
height: `32px`,
marginTop: `27px`,
padding: `0 12px`,
borderRadius: `3px`,
boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
fontSize: `14px`,
outline: `none`,
textOverflow: `ellipses`,
}}
/>
</SearchBox>
{props.isMarkerShown && (
<Marker position={fullPos} />
)}
</GoogleMap>
);
Where fullPos is the lat, lng variable I've been playing around with in different areas in hope it will work.
pulling the address external to the maps component
Not sure you mean Passing the new address from outside the component to it as a prop then, maybe you can use ComponentWillUpdate and make some beautiful conditions (to avoid bad endless loops) and also to check only if the passedAddressProp is changed, then maybe you can do something like: this.setState({center: passedAddressProp})
or
most likely obviously, you mean by it I get this address somewhere super far from this component so there's no chance they can communicate, then maybe the solution lies in redux/mobx (whichever you prefere/use) and when the address is changed, you can fire an action with the new address, and this component listens on this part of the state, also with some beautiful condition inside componentWillUpdate, you can change the this.state.center when this global part of the state changes.

Categories