When I navigate my app in startTabBasedApp (My 3 tabs) 1st screen to Render is the EventMap.js this is where my App crash. I just do not know why it crashing I tried to put console.log in all part of my codes but no error appeared.
So the main problem here is in the EventMap.js, because when I tried to remove the EventMap.js in my startTabBasedApp (Main Tabs) then uninstall the app, run react-native run-android, open the App navigate the Tabs (2) it works fine.
What I'm trying to do in my App is when user open the it and navigate it to the EventMap.js I want to get user's location instantly, just like in the Grab App.
How can I achieve this without crashing the App?
Here are my codes for EventMap.js
class EventMap extends Component {
constructor(props) {
super(props);
this.state = {
focusedLocation: {
latitude: 0,
longitude: 0,
latitudeDelta: 0.01,
longitudeDelta: Dimensions.get('window').width / Dimensions.get('window').height * 0.01
},
locationChosen: false,
markerPosition: {
latitude: 0,
longitude: 0
}
}
}
componentDidMount() {
this.didMountGetUserLocation();
};
//This is getting the location and exactly/automatically when they open
didMountGetUserLocation = () => {
navigator.geolocation.getCurrentPosition(pos => {
var lat = parseFloat(pos.coords.latitude)
var long = parseFloat(pos.coords.longitude)
var initialRegion = {
latitude: lat,
longitude: long,
latitudeDelta: 0.01,
longitudeDelta: Dimensions.get('window').width / Dimensions.get('window').height *0.01
};
this.setState({focusedLocation: initialRegion})
this.setState({locationChosen: true})
this.setState({markerPosition: initialRegion})
},
err => {
console.log(err);
});
};
pickLocationHandler = (event) => {
const coords = event.nativeEvent.coordinate;
//For animation of map
this.map.animateToRegion({
...this.state.focusedLocation,
latitude: coords.latitude,
longitude: coords.longitude
});
this.setState(prevState => {
return {
focusedLocation: {
...prevState.focusedLocation,
latitude: coords.latitude,
longitude: coords.longitude
},
locationChosen: true
};
});
};
getLocationHandler = () => {
navigator.geolocation.getCurrentPosition(pos => {
const coordsEvent = {
nativeEvent: {
coordinate: {
latitude: pos.coords.latitude,
longitude: pos.coords.longitude
}
}
};
this.pickLocationHandler(coordsEvent);
},
err => {
console.log(err);
alert("Fetching failed");
})
};
render() {
let marker = null;
if(this.state.locationChosen) {
marker = <MapView.Marker coordinate={this.state.markerPosition}/>
}
return(
<View style={{zIndex: -1}}>
<TouchableOpacity onPress={this.getLocationHandler} style={styles.iconContainer}>
<Icon name="md-locate" size={30} color="blue"/>
</TouchableOpacity>
<MapView
style={styles.map}
initialRegion={this.state.focusedLocation}
onPress={this.pickLocationHandler}
showsUserLocation={true}
ref={ref => this.map = ref} //For animating map movement
>
{marker}
</MapView>
</View>
);
}
}
Related
I am creating a React Native application, with Native Base and I use a map. As I would Like to have it usable on both Android and IOS I decided to use the package react-native-maps-osmdroid. Currently I am trying to make it work on Android. I am successful in showing the map, moving the map and adding markers to the map, but I see that the map is slowly moving northwest without me understanding why. To save a marker with the button I have added on the bottom of the map, the map either has to be tapped so it stands still or one has to continually tap the save-button until one triggers the save function between map-movements. Below is the map code.
import React, {useEffect, useState} from 'react';
import {StyleSheet, View} from 'react-native';
import {Button, Box, Text} from 'native-base';
import MapView, {
PROVIDER_OSMDROID,
Marker,
Polyline,
} from 'react-native-maps-osmdroid';
import {MarkerType} from '../helpers';
import CustomPin from '../../custom/CustomPin'; //svg
import CustomPosition from '../../custom/CustomPosition'; //svg
import {requestLocation} from '../../helpers/LocationService';
const style = StyleSheet.create({
map: {
...StyleSheet.absoluteFillObject,
},
button: {
padding: 10,
bottom: 10,
marginLeft: 2,
marginRight: 2,
},
});
/**
* Route parameters it might expect
* markers: List of lat/long positions to set as markers on the map.
* showControls: Whether the add / delete markers controls should be visible
* selfPosition:
*/
export default TripMap = ({navigation, route}) => {
const [markers, addMarkers] = useState(
route.params.markers ? [...route.params.markers] : [],
); //Current marker on the map. Will be populated through props when opening the map from a trip screen. Either through logging or adding a location. Will also be filled by this screen's add marker button.
const [markerControl, setMarkerControl] = useState(
route.params.showControls ? true : false,
); //Should the add marker/delete markers be shown
const positionSelf = route.params.selfPosition
? route.params.selfPosition
: null;
const [coordinatesArray, setCoordinatesArray] = useState([]);
const [selectedMarker, setSelectedMarker] = useState(null);
/*
Initial region to show on the map.
latitude and longitude are the values for the center of the map on the screen. Delta is how much around that point is showing, aka controls zoom. Lower the values to get better zoom.
*/
const [myRegion, setRegion] = useState(
route.params.position
? {
latitude: route.params.position.latitude,
longitude: route.params.position.longitude,
latitudeDelta: 0.05,
longitudeDelta: 0.09,
}
: {
latitude: route.params.markers
? route.params.markers[0].latlng.latitude
: 59.91355589226327,
longitude: route.params.markers
? route.params.markers[0].latlng.longitude
: 10.751138495614148,
latitudeDelta: 0.05,
longitudeDelta: 0.09,
},
);
useEffect(() => {
if (route.params.position) return;
getLocation();
if (route.params.markers) {
let tempArray = [];
route.params.markers.forEach(marker => {
tempArray.push(marker.latlng);
});
setCoordinatesArray(tempArray);
}
}, []);
const regionChange = async function (region) {
if (region !== null || region !== undefined)
region.latitudeDelta = Math.min(
region.latitudeDelta,
85 - Math.abs(region.latitude),
);
if (region.latitude >= 85) {
region.latitude = -85 + (region.latitude - 85);
} else if (region.latitude <= -85) {
region.latitude = 85 + (region.latitude + 85);
}
region.longitudeDelta = Math.min(
region.longitudeDelta,
180 - Math.abs(region.longitude),
);
if (region.longitude >= 180) {
region.longitude = -180 + (region.longitude - 180);
} else if (region.longitude <= -180) {
region.longitude = 180 + (region.longitude + 180);
}
setRegion(region);
};
const addMarker = async (lat, lng) => {
if (route.params.singleMarker === true) {
if (markers.length > 0) {
replaceMarker(lat, lng);
return;
}
}
let newMarker = {
title: 'Anchorage marker',
description: 'New anchorage marker',
latlng: {
latitude: lat,
longitude: lng,
},
draggable: true,
type: MarkerType.POSITION,
};
addMarkers(oldArray => [...oldArray, newMarker]);
};
const replaceMarker = async (lat, lng) => {
let newMarker = {
title: 'Anchorage marker',
description: 'New anchorage marker',
latlng: {
latitude: lat,
longitude: lng,
},
draggable: true,
type: MarkerType.POSITION,
};
addMarkers([newMarker]);
};
const saveMarker = async function () {
const returnScreen = route.params.returnScreen
? route.params.returnScreen
: 'LandingPage';
navigation.navigate(returnScreen, {
...route.params,
location: markers[0].latlng,
targetLocation: route.params.targetLocation
? route.params.targetLocation
: null,
});
};
const MarkerControlView = function () {
return (
<Box justifyContent="flex-end" style={{flexDirection: 'row'}}>
{route.params.singleMarker === true && markers.length > 0 && (
<Button
mt="3"
style={style.button}
onPress={saveMarker}
disabled={markers.length === 0}>
Lagre pin
</Button>
)}
{markers.length === 0 && (
<Button mt="2" style={style.button} onPress={addMarker}>
Legg til pin
</Button>
)}
</Box>
);
};
const DisplayControls = function (props) {
if (props.showControls) {
return <MarkerControlView />;
}
return <Box></Box>;
};
const getLocation = function () {
requestLocation(setRegion);
};
return (
<Box style={style.map} justifyContent="center">
<MapView
provider={PROVIDER_OSMDROID}
style={style.map}
minZoomLevel={3}
initialRegion={myRegion}
region={myRegion}
onRegionChangeComplete={regionChange}
onPress={mapEvent => {
addMarker(
mapEvent.nativeEvent.coordinate.latitude,
mapEvent.nativeEvent.coordinate.longitude,
);
}}>
<Polyline
coordinates={coordinatesArray}
strokeColor="#000"
strokeWidth={4}></Polyline>
{markers.map((marker, index) => (
<Marker
key={Math.random()}
rea
coordinate={marker.latlng}
title={marker.title}
description={marker.description}
draggable={marker.draggable}
onDragEnd={e => (marker.latlng = e.nativeEvent.coordinate)}
onPress={() => setSelectedMarker(marker)}
pinColor={'red'}>
<View style={{width: 50, height: 50}}>
<CustomPin width="50px" height="50px" color={marker.type.color} />
</View>
</Marker>
))}
{positionSelf !== null && (
<Marker key={positionSelf.latitude} coordinate={positionSelf}>
<View style={{width: 50, height: 50}}>
<CustomPosition />
</View>
</Marker>
)}
</MapView>
<Box alignItems="center" justifyContent="flex-end" style={style.map}>
<DisplayControls showControls={markerControl} />
</Box>
{selectedMarker && (
<Box alignItems="center" justifyContent="flex-end" style={style.map}>
<Text>{selectedMarker.title}</Text>
</Box>
)}
</Box>
);
};
I can clearly see the map move even without having touched it once, but it moves slowly.
The route parameter is versions of this: route: {"key": "TripMap-Zl5rO2SgH8kyJjYhWQumK", "name": "TripMap", "params": {"returnScreen": "AnchorageTabView", "showControls": true, "singleMarker": true}, "path": undefined}.
I am having trouble using setStates. I stored an array of markers for my Google Map in my state and I am using a for loop to iterate through each marker in order to change the position state of the marker using Google's Geocode API.
Here is my state:
state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {},
markers: [
{
name: "Costco Wholesale",
address: "9151 Bridgeport Rd, Richmond, BC V6X 3L9",
position: { lat: 0, lng: 0 },
placeID: 'ChIJWc2NzuF0hlQRDu0NNhdQCjM'
} //just trying to get this one to work first before I add in the others
],
busy: []
};
Here is the function(declared inside the class):
findLatLong(){
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.state.markers[i].position.setState({lat: lati, lng: lngi})
}
);
}
}
As you can see, I am passing the address contained in the same array element into the .fromAddress function and then using setState to set the lat and lng to the returned value.
I later call the function after the map renders but before the markers do:
<Map
google={this.props.google}
zoom={14}
style={mapStyles}
initialCenter={{ lat: 49.166590, lng: -123.133569 }}
>
{this.findLatLong}
{this.state.markers.map((marker, index) => (
<Marker
key={index}
onClick={this.onMarkerClick}
name={marker.name}
position={marker.position}
/>
))}
However marker's position state is not changing and is instead remaining as the filler values I passed during the initial state declaration.
Full code if it helps:
import React, { Component } from 'react';
import { Map, GoogleApiWrapper, InfoWindow, Marker } from 'google-maps-react';
import Geocode from 'react-geocode';
const key = '';
Geocode.setApiKey(key);
const mapStyles = {
width: '100%',
height: '100%'
};
export class MapContainer extends Component {
state = {
showingInfoWindow: false,
activeMarker: {},
selectedPlace: {},
markers: [
{
name: "Costco Wholesale",
address: "9151 Bridgeport Rd, Richmond, BC V6X 3L9",
position: { lat: 0, lng: 0 },
placeID: 'ChIJWc2NzuF0hlQRDu0NNhdQCjM'
}
],
busy: []
};
findLatLong(){
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.state.markers[i].position.setState({lat: lati, lng: lngi})
}
);
}
}
componentDidMount() {
this.getList();
}
getList = () => {
fetch('/api/getList')
.then(res => res.json())
.then(percent => this.setState({ busy: percent }))
}
onMarkerClick = (props, marker, e) =>
this.setState({
selectedPlace: props,
activeMarker: marker,
showingInfoWindow: true
});
onClose = props => {
if (this.state.showingInfoWindow) {
this.setState({
showingInfoWindow: false,
activeMarker: null
});
}
};
render() {
return (
<Map
google={this.props.google}
zoom={14}
style={mapStyles}
initialCenter={{ lat: 49.166590, lng: -123.133569 }}
>
{this.findLatLong}
{this.state.markers.map((marker, index) => (
<Marker
key={index}
onClick={this.onMarkerClick}
name={marker.name}
position={marker.position}
/>
))}
<InfoWindow
marker={this.state.activeMarker}
visible={this.state.showingInfoWindow}
onClose={this.onClose}
>
<div>
<h4>{this.state.selectedPlace.name}</h4>
<h4>{this.state.busy}</h4>
</div>
</InfoWindow>
</Map>
);
}
}
Thank you in advance!
Attempt to fix #1
.then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
this.setState(oldState => {
const newMarkers = [oldState.markers];
const modifiedMarker = newMarkers[i];
modifiedMarker.lat = lati;
modifiedMarker.lng = lngi;
return {oldState, markers: [newMarkers]};
//How do i implement the modifiedMarkers?
})
UPDATE
Actually it is better if you mutate the state just once and not inside the loop
findLatLong(){
const newMarkers = [...this.state.markers]
for(let i = 0; i < this.state.markers.length; i++){
Geocode.fromAddress(this.state.markers[i].address).then(
response => {
const { lati, lngi } = response.results[0].geometry.location;
newMarkers[i].position.lat = lati;
newMarkers[i].position.lng = lngi;
}
);
}
this.setState(oldState => {
return { ...oldState, markers: [...newMakers] };
});
}
That's no how you mutate the state, it should be something like this:
this.setState(oldState => {
const newMakers = [...oldState.makers];
const modifiedElement = newMakers[i];
modifiedElement.lat = lati;
modifiedElement.lng = lngi;
return { ...oldState, makers: [...newMakers] };
});
I want to display all the coordinates at the same time received via MQTT, but currently the code only displays the newest latitude and longitude pair. Does anyone have any advice?
constructor(props) {
super(props);
this.state = {
coordinates: [
{latitude: 0, longitude: 0}
]
};
};
componentDidMount() {
client.on('connect', () => {
client.subscribe('topic');
});
client.on('message', (_topic, message) => {
var parsedBody = JSON.parse(message.toString());
var mqttLat = parsedBody["latitude"];
var mqttLong = parsedBody["longitude"];
this.setState({
coordinates: [
{latitude: mqttLat, longitude: mqttLong}
]
});
});
};
<View>
<MapView>
{this.state.coordinates.map((marker, i) => (
<Marker
key = {i}
coordinate = {{
latitude: marker.latitude,
longitude: marker.longitude
}}>
</Marker>
))}
</MapView>
</View>
I guess that the problem is with the way you save your coordinates in the state. If you want to keep more coordinates than just one, push them to the coordinates array instead of overriding previous one.
client.on('connect', () => {
client.subscribe('topic');
});
client.on('message', (_topic, message) => {
var parsedBody = JSON.parse(message.toString());
var mqttLat = parsedBody["latitude"];
var mqttLong = parsedBody["longitude"];
this.setState({
coordinates: [
...this.state.coordinates,
{latitude: mqttLat, longitude: mqttLong}
]
});
});
};```
When I use Polyline it gives me this error:
attempt to invoke interface method 'java.util.iterator java.util.list.iterator()' on a null object
At first, I thought I made something wrong or I mis-used google-map API so I tried with some hard-coded coords (as shown in my code below) but without any progress.
The code will run fine if I remove the Polyline part.
I googled hoping to find any solution but without any success also.
some info my about dev platform:
expo version 2.19.1
yarn version 1.16.0
Node version 10.15.2
Testing on a physical device with android PI installed.
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Permissions, MapView } from 'expo'
// import Polyline from '#mapbox/polyline'
import { Polyline } from 'react-native-maps'
const locations = require('./locations.json')
export default class App extends React.Component {
state = {
latitude: null,
longitude: null,
locations: locations
}
componentDidMount() {
this.GetLocations()
}
GetLocations = async () => {
const { status } = await Permissions.getAsync(Permissions.LOCATION)
if (status !== 'granted') {
const response = await Permissions.askAsync(Permissions.LOCATION)
}
navigator.geolocation.getCurrentPosition(
({ coords: { latitude, longitude }}) => this.setState({ latitude, longitude}, this.mergeCoords),
(err) => console.log(`Error: ${err}`)
)
const { locations: [sampleLocation] } = this.state
this.setState({
desLatitude: sampleLocation.coords.latitude,
desLongitude: sampleLocation.coords.longitude,
}, this.mergeCoords)
}
mergeCoords = () => {
const { latitude, longitude, desLatitude, desLongitude } = this.state
const hasStartAndEnd = ( latitude !== null && desLatitude !== null )
// if the line have start and end
if (hasStartAndEnd) {
const concatStart = `${latitude},${longitude}`
const concatEnd = `${desLatitude},${desLongitude}`
this.getDirections(concatStart, concatEnd)
}
}
async getDirections(startLoc, desLoc) {
try {
// const res = await fetch(`https://maps.googleapis.com/maps/api/directions/json?key=MY_API_KEY&origin=${startLoc}&destination=${desLoc}`)
// const resJson = await res.json()
// const points = Polyline.decode(resJson.routes[0].overview_polyline.points)
// const coords = points.map( point => {
// return {
// latitude: point[0],
// longitude: point[1]
// }
// })
const coords = {
latitude: 31.262353,
longitude: 29.989506,
}
console.log("point, coords: ", coord)
this.setState({coords})
} catch(err) {
console.log('Error: ', err)
}
}
render() {
const { latitude, longitude, coords } = this.state
if (latitude) {
return (
<MapView
style={{ flex: 1 }}
showsUserLocation
initialRegion={{
latitude,
longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
<MapView.Polyline
strokeWidth={2}
strokeColor="red"
coordinates={coords}
/>
</MapView>
)
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>We need your permissions !!</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
//use condional rendering
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Permissions, MapView } from 'expo'
// import Polyline from '#mapbox/polyline'
import { Polyline } from 'react-native-maps'
const locations = require('./locations.json')
export default class App extends React.Component {
state = {
latitude: null,
longitude: null,
locations: locations,
direct : false
}
componentDidMount() {
this.GetLocations()
}
GetLocations = async () => {
const { status } = await Permissions.getAsync(Permissions.LOCATION)
if (status !== 'granted') {
const response = await Permissions.askAsync(Permissions.LOCATION)
}
navigator.geolocation.getCurrentPosition(
({ coords: { latitude, longitude }}) => this.setState({ latitude, longitude},
this.mergeCoords),
(err) => console.log(`Error: ${err}`)
)
const { locations: [sampleLocation] } = this.state
this.setState({
desLatitude: sampleLocation.coords.latitude,
desLongitude: sampleLocation.coords.longitude,
}, this.mergeCoords)
}
mergeCoords = () => {
const { latitude, longitude, desLatitude, desLongitude } = this.state
const hasStartAndEnd = ( latitude !== null && desLatitude !== null )
// if the line have start and end
if (hasStartAndEnd) {
const concatStart = `${latitude},${longitude}`
const concatEnd = `${desLatitude},${desLongitude}`
this.getDirections(concatStart, concatEnd)
}
}
async getDirections(startLoc, desLoc) {
try {
// const res = await fetch(`https://maps.googleapis.com/maps/api/directions/json?
key=MY_API_KEY&origin=${startLoc}&destination=${desLoc}`)
// const resJson = await res.json()
// const points = Polyline.decode(resJson.routes[0].overview_polyline.points)
// const coords = points.map( point => {
// return {
// latitude: point[0],
// longitude: point[1]
// }
// })
const coords = {
latitude: 31.262353,
longitude: 29.989506,
}
console.log("point, coords: ", coord)
this.setState({coords, direct:true})
} catch(err) {
console.log('Error: ', err)
}
}
render() {
const { latitude, longitude, coords } = this.state
if (latitude) {
return (
<MapView
style={{ flex: 1 }}
showsUserLocation
initialRegion={{
latitude,
longitude,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
}}
>
{this.state.direct &&
<MapView.Polyline
strokeWidth={2}
strokeColor="red"
coordinates={coords}
/>}
</MapView>
)
}
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center'}}>
<Text>We need your permissions !!</Text>
</View>
)
}
}
I have read the other questions related to this and tried implementing what the answers were on there.
They recommended adding /*global google */ - did not work
Next was to add const google = window.google; - did not work
I will post the code below and the error.
The error is happening where new google.maps is being called
Map.js:
/* global google */
import { default as React, Component } from 'react';
import raf from 'raf';
import canUseDOM from 'can-use-dom';
const google = window.google;
import { withGoogleMap, GoogleMap, Circle, InfoWindow, Marker } from 'react-google-maps';
import withScriptjs from 'react-google-maps/lib/async/withScriptjs';
const googleMapURL =
'https://maps.googleapis.com/maps/api/js?v=3.27&libraries=places,geometry&key=AIzaSyA7XEFRxE4Lm28tAh44M_568fCLOP_On3k';
const geolocation =
canUseDOM && navigator.geolocation
? navigator.geolocation
: {
getCurrentPosition(success, failure) {
failure("Your browser doesn't support geolocation.");
},
};
const GeolocationExampleGoogleMap = withScriptjs(
withGoogleMap(props =>
<GoogleMap defaultZoom={8} center={props.center}>
{props.center &&
<InfoWindow position={props.center}>
<div>User's Location</div>
</InfoWindow>}
{props.center &&
<Circle
center={props.center}
radius={props.radius}
options={{
fillColor: 'red',
fillOpacity: 0.2,
strokeColor: 'red',
strokeOpacity: 1,
strokeWeight: 1,
}}
/>}
>
{props.markers.map((marker, index) => {
const onClick = () => props.onMarkerClick(marker);
const onCloseClick = () => props.onCloseClick(marker);
return (
<Marker
key={index}
position={marker.position}
title={(index + 1).toString()}
onClick={onClick}
>
{marker.showInfo &&
<InfoWindow onCloseClick={onCloseClick}>
<div>
<strong>
{marker.content}
</strong>
<br />
<em>The contents of this InfoWindow are actually ReactElements.</em>
</div>
</InfoWindow>}
</Marker>
);
})}
</GoogleMap>,
),
);
function generateInitialMarkers() {
const southWest = new google.maps.LatLng(-31.203405, 125.244141);
const northEast = new google.maps.LatLng(-25.363882, 131.044922);
const lngSpan = northEast.lng() - southWest.lng();
const latSpan = northEast.lat() - southWest.lat();
const markers = [];
for (let i = 0; i < 5; i++) {
const position = new google.maps.LatLng(
southWest.lat() + latSpan * Math.random(),
southWest.lng() + lngSpan * Math.random(),
);
markers.push({
position,
content: 'This is the secret message'.split(' ')[i],
showInfo: false,
});
}
return markers;
}
export default class GeolocationExample extends Component {
constructor(props) {
super(props);
super(props);
this.state = {
center: null,
content: null,
radius: 6000,
markers: generateInitialMarkers(),
};
const isUnmounted = false;
handleMarkerClick = this.handleMarkerClick.bind(this);
handleCloseClick = this.handleCloseClick.bind(this);
}
handleMarkerClick(targetMarker) {
this.setState({
markers: this.state.markers.map((marker) => {
if (marker === targetMarker) {
return {
...marker,
showInfo: true,
};
}
return marker;
}),
});
}
handleCloseClick(targetMarker) {
this.setState({
markers: this.state.markers.map((marker) => {
if (marker === targetMarker) {
return {
...marker,
showInfo: false,
};
}
return marker;
}),
});
}
componentDidMount() {
const tick = () => {
if (this.isUnmounted) {
return;
}
this.setState({ radius: Math.max(this.state.radius - 20, 0) });
if (this.state.radius > 200) {
raf(tick);
}
};
geolocation.getCurrentPosition(
(position) => {
if (this.isUnmounted) {
return;
}
this.setState({
center: {
lat: position.coords.latitude,
lng: position.coords.longitude,
},
content: 'Location found using HTML5.',
});
raf(tick);
},
(reason) => {
if (this.isUnmounted) {
return;
}
this.setState({
center: {
lat: 60,
lng: 105,
},
content: `Error: The Geolocation service failed (${reason}).`,
});
},
);
}
componentWillUnmount() {
this.isUnmounted = true;
}
render() {
return (
<GeolocationExampleGoogleMap
googleMapURL={googleMapURL}
loadingElement={<div style={{ height: '100%' }}>loading...</div>}
containerElement={<div style={{ height: '100%' }} />}
mapElement={<div style={{ height: '100%' }} />}
center={this.state.center}
content={this.state.content}
radius={this.state.radius}
onMarkerClick={this.handleMarkerClick}
onCloseClick={this.handleCloseClick}
markers={this.state.markers}
/>
);
}
}
You are loading async script. When you initialize google constant there is no google object. You can solve this by using 'ref' for map component. Ref callback fired when google object exists. For example:
<GoogleMap defaultZoom={8} center={props.center} ref={()=>{props.onMapLoad}}>...</GoogleMap>
...
constructor(props) {
...
this.onMapLoad = this.onMapLoad.bind(this)
}
...
onMapLoad() {
/*init markers and all objects with "google" here*/
}
...
<GeolocationExampleGoogleMap
onMapLoad={this.onMapLoad}
...
/>
and, of course, do not init google const, use just google object instead,