React Google Maps Api doesn't render children elements at first render - javascript

I'm trying to use Google Maps Api in my app, everything is fine until I want to display a Marker at the first render of the map. The Marker is not showing up, but if I add one more Marker after the render is done, the Marker will appear.
So the problem is that I want to render the map with a Marker already there, I don't want to wait for some location to be selected.
I want to receive lat and lng from props, but for now I've made an hard coded const (center).
import React, { useMemo } from "react";
import { useJsApiLoader, GoogleMap, Marker } from "#react-google-maps/api";
export default function GoogleMaps({ lat, lng }) {
const { isLoaded } = useJsApiLoader({
googleMapsApiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY,
});
const center = useMemo(() => ({ lat: 42.4332, lng: 20.4343 }), []);
if (!isLoaded) {
return <h2>Calculating Locations..</h2>;
}
return (
isLoaded && (
<GoogleMap
center={center}
zoom={17}
mapContainerStyle={{ width: "450px", height: "400px" }}
options={{ disableDefaultUI: true, mapId: "deleted for this snippet" }}
>
<Marker position={center} />
</GoogleMap>
)
);
}

Have you tried importing and using MarkerF instead of Marker?
See: https://github.com/JustFly1984/react-google-maps-api/issues/3048#issuecomment-1166410403
"MarkerF is functional component vs class based Marker component, which does not work with react Strict and/or react#17+"
Also, there are similar issues discussed here: Markers not rendering using #react-google-maps/api and here: Map Marker don't show up (Marker rendered before Map)- ReactJS with #react-google-maps/api

Related

how to integrate google maps in react using package google-maps-react?

When I use google-maps-react to integrate maps, map loads correctly and even shows the correct markers but I am having some issues.
1- A styling issue normally map component overlays the content I think because it has position absolute but when I change its position to relative it does not show. I have placed it in a div everything above the div shows but it overlays the content below the div.
2- it is giving errors in the console (I am listing them below)
Using UNSAFE_componentWillReceiveProps in strict mode is not recommended and may indicate bugs in your code. Move data fetching code or side effects to componentDidUpdate.If you're updating state whenever props change, refactor your code to use memoization techniques or move it to static getDerivedStateFromProps.
Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to this.state directly or define a state = {}; class property with the desired state in the Wrapper component.
My mapComponent:
import React from "react";
import { Map, Marker, GoogleApiWrapper } from "google-maps-react";
export function MapContainer({ google, captains = [] }) {
const mapStyles = {
width: "85%",
height: "100%",
};
return (
<Map
google={google}
// containerStyle={{
// position: "absolute",
// width: "85%",
// height: "40%",
// }}
// style={mapStyles}
containerStyle={mapStyles}
initialCenter={{
lat: captains[0].location.coordinates[1],
lng: captains[0].location.coordinates[0],
}}
zoom={captains.length === 1 ? 18 : 13}
>
{captains.map((captain) => (
<Marker
key={captain._id}
position={{
lat: captain.location.coordinates[1],
lng: captain.location.coordinates[0],
}}
/>
))}
</Map>
);
}
export default GoogleApiWrapper({
apiKey: "#############################",
})(MapContainer);
Here is where I am using it:
import MapContainer from "../components/MapContainer";
function Captains({ captains }) {
return (
<div className=" h-screen overflow-auto">
<div className="pt-24 pl-20 flex flex-col">
<othercontent ..... />
<div className="visible h-1/3 w-10/12 mx-5">
<MapContainer captains={captains} />
</div>
<PaginationTable
.....
/>
</div>
</div>
</>
);
}

google-maps-react centers me in the middle of the ocean when given new bounds

I am using the google-maps-react package and I am trying to have bounds for my map. They should change based on values passed to the component through props. It does successfully do this, but after the first load of my website instead of reloading the map so that I can see all the markers, it just puts me at lat: 0.0 and long: 0.0. If I zoom out I can see all of my markers, but the map does not resize itself.
It does successful load! Just doesn't load the bounds. See the images below.
After I save my file and it reloads
After I leave the page and come back, or refresh
Here is what I've tried:
import { Map, Marker, GoogleApiWrapper } from "google-maps-react";
class MapExample extends Component {
constructor(props) {
super(props);
this.state = {
bounds: null
};
this.handleMapLoad = this.handleMapLoad.bind(this);
}
handleMapLoad() {
const bounds = new this.props.google.maps.LatLngBounds();
for (let loc of this.props.originsCoords) bounds.extend({ lat: loc.lat, lng: loc.lng });
this.setState({bounds:bounds});
}
render() {
return (
<Map
onReady={this.handleMapLoad}
google={this.props.google}
bounds={this.state.bounds}
style={{width:'50%', height:'50%'}}
>
{this.props.originsCoords.map((loc, i) => (
<Marker key={i} position={{ lat: loc.lat, lng: loc.lng }} />
))}
</Map>
);
}
}
export default GoogleApiWrapper({
apiKey: "api-key"
})(MapExample);

onCenterChange callback returns undefined #react-google-maps/api

I have been using a library called #react-google-maps/api and I want to store the map center as react state and I want the user to be able to drag the map while the marker always stays at the center of the map (uber style location selection)
The Problem is when I call the onCenterChange of the component, it returns me undefined
and when after store the map instance (recieved on the onLoad callback) as react state. The map instance returns the exact same center everytime (I guess the state save is static)
<GoogleMap
id={id}
zoom={zoom}
center={center}
options={options}
mapContainerStyle={{ width, height }}
onLoad={m => {
if (!map) setMap(m);
}}
onCenterChanged={e => {
console.log(map);
if (map) {
console.log(parseCoords(map.getCenter()));
}
}}
>
{children}
</GoogleMap>
Indeed, onCenterChanged event does not accept any arguments in #react-google-maps/api:
onCenterChanged?: () => void;
Instead map instance could be retrieved via onLoad event handler and map center saved in state like this:
function Map(props) {
const mapRef = useRef(null);
const [position, setPosition] = useState({
lat: -25.0270548,
lng: 115.1824598
});
function handleLoad(map) {
mapRef.current = map;
}
function handleCenterChanged() {
if (!mapRef.current) return;
const newPos = mapRef.current.getCenter().toJSON();
setPosition(newPos);
}
return (
<GoogleMap
onLoad={handleLoad}
onCenterChanged={handleCenterChanged}
zoom={props.zoom}
center={props.center}
id="map"
>
</GoogleMap>
);
}
Here is a demo which demonstrates how to keep the marker centered of the map while dragging the map.

Opening Google Map onClicking the Button | Reactjs

I have a map component, in that, I used Google-map-react library to display locations in google map. Inside that map, I am having a button called "View in maps". So, now, if the user clicks on that button. it should take them to the google map with given location coordinates. Please find code below and let me know, how can I achieve that
import React, { Component } from 'react';
import { withStyles } from '#material-ui/core/styles';
import styles from '../../../../../../assets/css/Me.style.js';
import GoogleMapReact from 'google-map-react';
import { Typography, Button } from '#material-ui/core';
import Marker from '#material-ui/icons/LocationOnOutlined'
class DetailsMap extends Component {
static defaultProps = {
center: { lat: 40.7446790, lng: -73.9485420 },
};
render() {
const {classes} = this.props;
return (
<div className={classes.root}>
<div className={classes.googleMap}>
<GoogleMapReact
zoom = {11}
onClick={this.onClick}
defaultCenter={ this.props.center }
>
<Marker
style={{color: '#ff7777'}}
lat={40.7473310}
lng={-73.8517440}
/>
<div className={classes.address}>
<div className={classes.addressWrapper}>
<Typography className={classes.addressHead}>
Address
</Typography>
<Typography className={classes.addressContent}>
221, raj start, doler street<br />
QC J9PB6X
</Typography>
<Button variant='outlined' className={classes.view}>
View in Maps
</Button>
</div>
</div>
</GoogleMapReact>
</div>
</div>
)
}
}
export default withStyles(styles, {withTheme:true})(DetailsMap);
I use this code for show google map in new tab with specific location with marker.
const showInMapClicked = () => {
window.open("https://maps.google.com?q="+your_lat+","+your_lng );
};
Google maps can take GET parameters for coordinates to open on_load. Make an href to this address
https://www.google.com/maps/#${your_lat},${your_lng},${your_desired_zoom}z
Note
To be able to use the formating provided in the above answer you have to use `` quotes over the normal " " or ' '

Dynamically Adding Markers on google-map-react

What I wan't to do is to show the location picked from some mobile devices on the Map.
Data about the locations are there..
What I need here is to add Markers on the map depending on the data received from the server.
Assume I have set the location data ({Lat,Lang}) to the state markers
Then How can I add this to show in Map.
My Map Code is as follows!
import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
const AnyReactComponent = ({ text }) => <div>{text}</div>;
class MyClass extends Component {
constructor(props){
super(props);
}
render() {
return (
<GoogleMapReact
defaultCenter={this.props.center}
defaultZoom={this.props.zoom}
style={{height: '300px'}}
>
<AnyReactComponent
lat={59.955413}
lng={30.337844}
text={'Google Map'}
/>
</GoogleMapReact>
);
}
}
MyClass.defaultProps = {
center: {lat: 59.95, lng: 30.33},
zoom: 11
};
export default MyClass;
This Code is from the answer Implementing google maps with react
Used npm package :- google-map-react
You may try:
import React, { Component } from 'react';
import GoogleMapReact from 'google-map-react';
const AnyReactComponent = ({ img_src }) => <div><img src={img_src} className="YOUR-CLASS-NAME" style={{}} /></div>;
class MyClass extends Component {
constructor(props){
super(props);
this.state = {
markers: [],
}
}
componentDidMount(){
// or you can set markers list somewhere else
// please also set your correct lat & lng
// you may only use 1 image for all markers, if then, remove the img_src attribute ^^
this.setState({
markers: [{lat: xxxx, lng: xxxx, img_src: 'YOUR-IMG-SRC'},{lat: xxxx, lng: xxxx, img_src: 'YOUR-IMG-SRC' },{lat: xxxx, lng: xxxx, img_src: 'YOUR-IMG-SRC'}],
});
}
render() {
return (
<GoogleMapReact
defaultCenter={this.props.center}
defaultZoom={this.props.zoom}
style={{height: '300px'}}
>
{this.state.markers.map((marker, i) =>{
return(
<AnyReactComponent
lat={marker.lat}
lng={marker.lng}
img_src={marker.img_src}
/>
)
})}
</GoogleMapReact>
);
}
}
MyClass.defaultProps = {
center: {lat: 59.95, lng: 30.33},
zoom: 11
};
If this has error, please show here too, then we can fix it later
===========
ADDED EXAMPLE FOR CLICK-EVENT ON MARKERS
markerClicked(marker) {
console.log("The marker that was clicked is", marker);
// you may do many things with the "marker" object, please see more on tutorial of the library's author:
// https://github.com/istarkov/google-map-react/blob/master/API.md#onchildclick-func
// Look at their examples and you may have some ideas, you can also have the hover effect on markers, but it's a bit more complicated I think
}
render() {
return (
<GoogleMapReact
defaultCenter={this.props.center}
defaultZoom={this.props.zoom}
style={{height: '300px'}}
>
{this.state.markers.map((marker, i) =>{
return(
<AnyReactComponent
lat={marker.lat}
lng={marker.lng}
img_src={marker.img_src}
onChildClick={this.markerClicked.bind(this, marker)}
/>
)
})}
</GoogleMapReact>
);
}
Once again, post here some errors if any ^^ !
Be careful. You said react-google-map but you are using google-map-react. Those are 2 different packages. Do not mix up their documentation.

Categories

Resources