Google Maps MarkerClusterer in React with #react-google-maps/api - google-maps

I am getting an error while I want to implement MarkerClusterer from #react-google-maps/api.
The error that I am getting is
No overload matches this call.
Overload 1 of 2, '(props: MarkerClustererProps | Readonly): ClustererComponent', gave the following error.
Type 'Element[]' is missing the following properties from type 'ReactElement<any, any>': type, props, key
Overload 2 of 2, '(props: MarkerClustererProps, context: any): ClustererComponent', gave the following error.
Type 'Element[]' is not assignable to type 'Element'.ts(2769)
index.d.ts(378, 15): The expected type comes from the return type of this signature.
index.d.ts(378, 15): The expected type comes from the return type of this signature.
You can check the codes below. (I am sharing only the relevant parts of my whole code)
import React, { useEffect, useState, useRef } from 'react';
import { GoogleMap, useJsApiLoader, Marker, MARKER_LAYER, OverlayView, MarkerClusterer } from '#react-google-maps/api';
import './app.css';
import PlacesAutocomplete from './components/PlacesAutocomplete';
const containerStyle = {
width: '100vw',
height: '100vh',
};
const App = () => {
const [center, setCenter] = useState({ lat: 39.015137, lng: 34.97953 });
const [zoom, setZoom] = useState(6);
const [markers, setMarkers] = useState<{ id: string; name: string; avatar: string; latLng?: google.maps.LatLng }[]>([]);
const [users, setUsers] = useState<{ id: string; name: string; role: string; avatar: string; color: string; latLng: boolean }[]>([]);
const mounted = useRef(false);
const markerRef = useRef<Marker>(null);
const { isLoaded } = useJsApiLoader({
id: 'google-map-script',
googleMapsApiKey: 'API_KEY',
libraries: ['places'],
});
let markersInfo: { id: string; name: string; avatar: string; latLng?: google.maps.LatLng }[] = [];
return isLoaded ? (
<>
<PlacesAutocomplete setCenter={setCenter} setZoom={setZoom} />
<GoogleMap mapContainerStyle={containerStyle} center={center} zoom={zoom} onClick={handleAddMarker}>
<>
<OverlayView
position={{ lat: -34.397, lng: 150.644 }}
mapPaneName={OverlayView.OVERLAY_MOUSE_TARGET}
>
<>
<MarkerClusterer>
{clusterer => markers?.map((obj: any, i) => (
<Marker
onClick={handleMarkerHover}
ref={markerRef}
key={i}
position={obj.latLng}
label={{
// text: obj.name,
text: obj.avatar
? obj.name
: obj.name
.split(' ')
.map((name: string) => name[0])
.join('')
.toUpperCase(),
className: obj.avatar ? `marker-label-with-avatar` : 'marker-label-without-avatar',
}}
icon={{
scaledSize: new google.maps.Size(50, 50),
url: obj.avatar ? obj.avatar + '#custom_marker' : 'avatar_default.png' + '#custom_marker_w/o_avatar',
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(25, 50),
}}
animation={google.maps.Animation.DROP}
// draggable={true}
/>
))}
</MarkerClusterer>
</>
</OverlayView>
</>
</GoogleMap>
</>
) : (
<></>
);
};
export default React.memo(App);

The expected return from function(clusterer: Clusterer) is a JSX.Element. So I would suggest the following changes:
<MarkerClusterer>
{(clusterer) => (
<div>
{markers?.map((obj: any, i) => (
<Marker
onClick={handleMarkerHover}
ref={markerRef}
key={i}
position={obj.latLng}
label={{
// text: obj.name,
text: obj.avatar
? obj.name
: obj.name
.split(' ')
.map((name: string) => name[0])
.join('')
.toUpperCase(),
className: obj.avatar ? `marker-label-with-avatar` : 'marker-label-without-avatar',
}}
icon={{
scaledSize: new google.maps.Size(50, 50),
url: obj.avatar
? obj.avatar + '#custom_marker'
: 'avatar_default.png' + '#custom_marker_w/o_avatar',
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(25, 50),
}}
animation={google.maps.Animation.DROP}
// draggable={true}
/>
))}
</div>
)}
</MarkerClusterer>

Related

Google Maps API, Marker onClick listener not working as intended

right now I'm trying to build a map that shows all the hospitals in Indonesia (and later on about covid cases) and so far I've been able to successfully grab locations from a json file and map it onto a map. My map has a button such that if you click it all the hospitals in Indonesia will show up on the map as markers. What I want to do now is to have an InfoWindow pop-up of the hospital name when a user clicks on a specific marker.
How I tried to approach it:
Create a state boolean array for all hospital markers to see if the hospital has been clicked
If the hospital has been clicked, output an InfoWindow with the Hospitals name.
Issue:
It seems that when I click the button to show all hospitals in Indonesia, it updates the state boolean array to all true. I'm not sure why that is the case, and when I click on a specific marker the state array is unchanged.
This is my git repo if you need the full code: https://github.com/ktanojo17505/google-map-react
Here is my state:
state = {
address: "",
city: "",
area: "",
state: "",
zoom: 11,
height: 400,
mapPosition: {
lat: 0,
lng: 0
},
markerPosition: {
lat: 0,
lng: 0
},
placeHospitals: false,
Hospitals: [],
didClickHospital: []
};
This is my constructor:
constructor(props) {
super(props);
var HospitalLocations = [];
var clickHospital = [];
var position;
var hospitalName;
var id;
for (let index = 0; index < HospitalData.hospitals.length; ++index) {
id = index;
var latitude = HospitalData.hospitals[index].latitude;
var longitude = HospitalData.hospitals[index].longitude;
position = { latitude, longitude };
hospitalName = HospitalData.hospitals[index].nama;
var entry = { id, position, hospitalName };
HospitalLocations.push(entry);
clickHospital.push(false);
}
this.state.Hospitals = HospitalLocations;
this.state.didClickHospital = clickHospital;
}
This is my return
return (
<div style={{ padding: "1rem", margin: "0 auto", maxWidth: 1000 }}>
<h1>Google Maps Basic</h1>
<Descriptions bordered>
<Descriptions.Item label="City">{this.state.city}</Descriptions.Item>
<Descriptions.Item label="Area">{this.state.area}</Descriptions.Item>
<Descriptions.Item label="State">
{this.state.state}
</Descriptions.Item>
<Descriptions.Item label="Address">
{this.state.address}
</Descriptions.Item>
</Descriptions>
<MapWithAMarker
googleMapURL={
"https://maps.googleapis.com/maps/api/js?key=" +
config.GOOGLE_API_KEY +
"&v=3.exp&libraries=geometry,drawing,places"
}
loadingElement={<div style={{ height: `100%` }} />}
containerElement={<div style={{ height: `400px` }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
<div style={{ marginTop: "2.5rem" }}>
<Button onClick={this.placeHospitals}>Hospitals</Button>
</div>
</div>
);
MapwithMarker
const MapWithAMarker = withScriptjs(
withGoogleMap(props => (
<div>
<GoogleMap
defaultZoom={this.state.zoom}
defaultCenter={{
lat: this.state.mapPosition.lat,
lng: this.state.mapPosition.lng
}}
options={options}
onClick={this.placeMarker}
>
<Marker
draggable={true}
onDragEnd={this.onMarkerDragEnd}
position={{
lat: this.state.markerPosition.lat,
lng: this.state.markerPosition.lng
}}
>
<InfoWindow>
<div>{this.state.address}</div>
</InfoWindow>
</Marker>
{this.state.placeHospitals &&
this.state.Hospitals.map(hospitalLoc => ( // Place the locations if Hospitals Button is clicked
<Marker
draggable={false}
position={{
lat: hospitalLoc.position.latitude,
lng: hospitalLoc.position.longitude
}}
key={hospitalLoc.id}
onClick={this.clickHospital(hospitalLoc.id)} // Change the state of the Hospital InfoWindow
>
{/* {this.state.didClickHospital[index] && ( // If true output an infowindow of the hospital name
<InfoWindow>
<div>{hospitalLoc.name}</div>
</InfoWindow>
)} */}
</Marker>
))}
<AutoComplete
style={{
width: "100%",
height: "40px",
paddingLeft: 16,
marginTop: 2,
marginBottom: "2rem"
}}
types={["(regions)"]}
onPlaceSelected={this.onPlaceSelected}
/>
</GoogleMap>
</div>
))
);
clickHospital
clickHospital = id => {
console.log("clicked");
// var tempClickHospital = this.state.didClickHospital;
// console.log(tempClickHospital[index]);
// tempClickHospital[index] = !tempClickHospital[index];
// console.log(tempClickHospital[index]);
// this.setState({ didClickHospital: tempClickHospital });
// console.log(this.state.didClickHospital);
};
This is the output of my code (before clicking Hospitals)1
This is the output of my code (after clicking Hospitals)2
If anyone could point out what I'm doing wrong that would be helpful thank you!
You can directly map each data from the json file to create an individual <Marker> with <InfoWindow> inside it.
Here's a working sample code and the code snippet below on how to do this:
import React, { Component } from "react";
import {
withGoogleMap,
GoogleMap,
Marker,
InfoWindow
} from "react-google-maps";
//import the json data of your hospital info
import data from "./data.json";
import "./style.css";
class Map extends Component {
constructor(props) {
super(props);
this.state = {
hospitalId: "",
addMarkerBtn: false
};
}
addMarkerFunction = () => {
this.setState({
addMarkerBtn: true
});
};
handleToggleOpen = id => {
this.setState({
hospitalId: id
});
};
render() {
const GoogleMapExample = withGoogleMap(props => (
<GoogleMap
defaultCenter={{ lat: -6.208763, lng: 106.845599 }}
defaultZoom={16}
>
{this.state.addMarkerBtn === true &&
data.map(hospital => (
<Marker
key={hospital.id}
position={{ lat: hospital.lat, lng: hospital.lng }}
onClick={() => this.handleToggleOpen(hospital.id)}
>
{this.state.hospitalId === hospital.id && (
<InfoWindow
onCloseClick={this.props.handleCloseCall}
options={{ maxWidth: 100 }}
>
<span>{hospital.id}</span>
</InfoWindow>
)}
</Marker>
))}
</GoogleMap>
));
return (
<div>
<button id="addMarker" onClick={() => this.addMarkerFunction()}>
Add Marker
</button>
<GoogleMapExample
containerElement={<div style={{ height: `500px`, width: "500px" }} />}
mapElement={<div style={{ height: `100%` }} />}
/>
</div>
);
}
}
export default Map;

`Error while updating property 'region' of a view managed by: AIRMap null Longitude'

I want to make a map where user can select his current location as well and can select location from other than his current location...But i am getting this error ... "Error while updating property 'region' of a view managed by: AIRMap null Longitude"......Here i am attaching my Map Class code too ...Please help me
import React from 'react';
import PropTypes from 'prop-types';
import { View, StyleSheet, Animated, Platform, UIManager, TouchableOpacity, Text, ViewPropTypes } from 'react-native';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import Entypo from 'react-native-vector-icons/Entypo';
import axios from 'axios';
import Events from 'react-native-simple-events';
import MapView from 'react-native-maps';
import AutoCompleteInput from './AutoCompleteInput'
const PLACE_DETAIL_URL = 'https://maps.googleapis.com/maps/api/place/details/json';
const DEFAULT_DELTA = { latitudeDelta: 0.015, longitudeDelta: 0.0121 };
export default class Map extends React.Component {
static propTypes = {
apiKey:"AIzaSyCqDF-mH8qkUQ4z0qB1exxxxxxI0FYRACs",
initialLocation: PropTypes.shape({
latitude: PropTypes.number,
longitude: PropTypes.number,
}).isRequired,
markerColor: PropTypes.string,
actionButtonStyle: ViewPropTypes.style,
actionTextStyle: Text.propTypes.style,
actionText: PropTypes.string,
onLocationSelect: PropTypes.func,
debounceDuration: PropTypes.number,
components: PropTypes.arrayOf(PropTypes.string),
};
static defaultProps = {
markerColor: 'black',
actionText: 'DONE',
onLocationSelect: () => ({}),
debounceDuration: 300,
components: [],
};
constructor(props) {
super(props);
if (Platform.OS === 'android')
{
UIManager.setLayoutAnimationEnabledExperimental &&
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}
componentDidMount() {
Events.listen('InputBlur', this.constructor.displayName, this._onTextBlur);
Events.listen('InputFocus', this.constructor.displayName, this._onTextFocus);
Events.listen('PlaceSelected', this.constructor.displayName, this._onPlaceSelected);
}
componentWillUnmount() {
Events.rm('InputBlur', this.constructor.displayName);
Events.rm('InputFocus', this.constructor.displayName);
Events.rm('PlaceSelected', this.constructor.displayName);
}
state = {
inputScale: new Animated.Value(1),
inFocus: false,
region: {
...DEFAULT_DELTA,
...this.props.initialLocation,
},
};
_animateInput = () => {
Animated.timing(this.state.inputScale, {
toValue: this.state.inFocus ? 1.2 : 1,
duration: 300,
}).start();
};
_onMapRegionChange = region => {
this._setRegion(region, false);
if (this.state.inFocus) {
this._input.blur();
}
};
_onMapRegionChangeComplete = region => {
this._input.fetchAddressForLocation(region);
};
_onTextFocus = () => {
this.state.inFocus = true;
this._animateInput();
};
_onTextBlur = () => {
this.state.inFocus = false;
this._animateInput();
};
_setRegion = (region, animate = true) => {
this.state.region = { ...this.state.region, ...region };
if (animate) this._map.animateToRegion(this.state.region);
};
_onPlaceSelected = placeId => {
this._input.blur();
axios.get(`${PLACE_DETAIL_URL}?key=${this.props.apiKey}&placeid=${placeId}`).then(({ data }) => {
let region = (({ lat, lng }) => ({ latitude: lat, longitude: lng }))(data.result.geometry.location);
this._setRegion(region);
});
};
_getCurrentLocation = () => {
navigator.geolocation.getCurrentPosition(position => {
let location = (({ latitude, longitude }) => ({ latitude, longitude }))(position.coords);
this._setRegion(location);
});
};
render() {
let { inputScale } = this.state;
return (
<View style={styles.container}>
<MapView
ref={mapView => (this._map = mapView)}
style={styles.mapView}
region={this.state.region}
showsMyLocationButton={true}
showsUserLocation={false}
onPress={({ nativeEvent }) => this._setRegion(nativeEvent.coordinate)}
onRegionChange={this._onMapRegionChange}
onRegionChangeComplete={this._onMapRegionChangeComplete}
/>
<Entypo
name={'location-pin'}
size={30}
color={this.props.markerColor}
style={{ backgroundColor: 'transparent' }}
/>
<View style={styles.fullWidthContainer}>
<AutoCompleteInput
ref={input => (this._input = input)}
apiKey={this.props.apiKey}
style={[styles.input, { transform: [{ scale: inputScale }] }]}
debounceDuration={this.props.debounceDuration}
components={this.props.components}
/>
</View>
<TouchableOpacity
style={[styles.currentLocBtn, { backgroundColor: this.props.markerColor }]}
onPress={this._getCurrentLocation}
>
<MaterialIcons name={'my-location'} color={'white'} size={25} />
</TouchableOpacity>
<TouchableOpacity
style={[styles.actionButton, this.props.actionButtonStyle]}
onPress={() => this.props.onLocationSelect({ ...this.state.region, address: this._input.getAddress() })}
>
<View>
<Text style={[styles.actionText, this.props.actionTextStyle]}>{this.props.actionText}</Text>
</View>
</TouchableOpacity>
{this.props.children}
</View>
);
}
}
If you use showsUserLocation props you need to add the ACCESS_FINE_LOCATION permission into your AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
hope it will help!
first set default region so that it wont crash on start.
const LATITUDE = 40.665364;
const LONGITUDE = -74.213377;
const LATITUDE_DELTA = 0.0043;
const LONGITUDE_DELTA = 0.0034;
set region props default value this.state.region which is null, which cause this error try adding its default value in state. like this
state = {
region:{
latitude: LATITUDE,
longitude: LONGITUDE,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA
}
}
<MapView
ref={map => (this.map = map)}
customMapStyle={uber_style}
initialRegion={{
latitude: LATITUDE,
longitude: LONGITUDE,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGITUDE_DELTA
}}
region={this.state.region}
onMapReady={this.onMapLayout}
maxZoomLevel={this.state.maxZoomLevel}
provider={PROVIDER_GOOGLE}
loadingIndicatorColor="#e21d1d"
style={{
flex: 1,
width: Metrics.screenWidth,
height: Metrics.screenHeight
}}
showsBuildings={true}
loadingEnabled={true}
// showsUserLocation={true}
onRegionChangeComplete={this.onRegionChangeComplete}
>
Below is my sample code:
var coords = this.props.navigation.state.params.locationvalue; //getting location from props.
try {
this.map.animateToRegion({
...this.state.locationArea,
latitude: coords.latitude,
longitude: coords.longitude
});
this.setState(prevState => {
return {
locationArea: {
...prevState.locationArea,
latitude: coords.latitude,
longitude: coords.longitude
}
};
});
} catch (error) {
console.log("error map.animateRegion(): " + JSON.stringify(error))
}
Here I was passing the wrong value of latitude and longitude when using this.map.animateToRegion method.
You can check that you are passing the exact value of latitude and longitude while using animateToRegion with MapView. I hope this solution helps.
For me, the issue was a typo error. Region lat and long are in a string. Also, it shouldn’t be blank or undefined .
You can use Number or parseFloat to parse.
const LATITUDE = '70.664'; //type string
const LONGITUDE = '-58.23077';
Fix to this is :
region:{
latitude: parseFloat(LATITUDE), //or Number(LATITUDE)
longitude: parseFloat(LONGITUDE),
latitudeDelta: 0.02,
longitudeDelta: 0.02,
}

Maps blank react native

I'm having a problem while viewing google maps in my react native app. I ran a test with an HTML file and it displays. But in my app open blank but shows the logo of google. Below my map code.
App.js
import React, { Component, Fragment } from 'react';
import { View, Image } from 'react-native';
import MapView, { Marker } from 'react-native-maps';
import Geocoder from 'react-native-geocoding';
import { getPixelSize } from '../../components/utils';
import Search from '../Search';
import Directions from '../Directions';
import Details from '../Details';
import markerImage from '../../assets/marker.png';
import backImage from '../../assets/back.png';
import {
Back,
LocationBox,
LocationText,
LocationTimeBox,
LocationTimeText,
LocationTimeTextSmall
} from './styles';
Geocoder.init('MY API');
export default class Map extends Component {
state = {
region: null,
destination: null,
duration: null,
location: null
};
async componentDidMount () {
navigator.geolocation.getCurrentPosition(
async ({ coords: { latitude, longitude } }) => {
const response = await Geocoder.from({ latitude, longitude });
const address = response.results[0].formatted_address;
const location = address.substring(0, address.indexOf(','));
console.log(latitude);
console.log(longitude);
this.setState({
location,
region: {
latitude,
longitude,
latitudeDelta: 0.0143,
longitudeDelta: 0.0134
}
});
}, // sucesso
() => {}, // erro
{
timeout: 2000,
enableHighAccuracy: true,
maximumAge: 1000
}
);
}
handleLocationSelected = (data, { geometry }) => {
const {
location: { lat: latitude, lng: longitude }
} = geometry;
this.setState({
destination: {
latitude,
longitude,
title: data.structured_formatting.main_text
}
});
};
handleBack = () => {
this.setState({ destination: null });
};
render () {
const { region, destination, duration, location } = this.state;
return (
<View style={{ flex: 1 }}>
<MapView
style={{ flex: 1 }}
region={region}
showsUserLocation
loadingEnabled
ref={el => (this.mapView = el)}
>
{destination && (
<Fragment>
<Directions
origin={region}
destination={destination}
onReady={result => {
this.setState({ duration: Math.floor(result.duration) });
this.mapView.fitToCoordinates(result.coordinates, {
edgePadding: {
right: getPixelSize(50),
left: getPixelSize(50),
top: getPixelSize(50),
bottom: getPixelSize(350)
}
});
}}
/>
<Marker
coordinate={destination}
anchor={{ x: 0, y: 0 }}
image={markerImage}
>
<LocationBox>
<LocationText>{destination.title}</LocationText>
</LocationBox>
</Marker>
<Marker coordinate={region} anchor={{ x: 0, y: 0 }}>
<LocationBox>
<LocationTimeBox>
<LocationTimeText>{duration}</LocationTimeText>
<LocationTimeTextSmall>MIN</LocationTimeTextSmall>
</LocationTimeBox>
<LocationText>{location}</LocationText>
</LocationBox>
</Marker>
</Fragment>
)}
</MapView>
{destination ? (
<Fragment>
<Back onPress={this.handleBack}>
<Image source={backImage} />
</Back>
<Details />
</Fragment>
) : (
<Search onLocationSelected={this.handleLocationSelected} />
)}
</View>
);
}
}
In androidManifest i put the correct code and the rest also, I do not know what else to do , I think it might be something with my emulator, can anyone give me a guideline?
you need to install google play services or Gapps on emulator.

react-google-maps InfoWindow not displayed

I'm trying to open an infoWindow when I click on a marker.
I followed documentation step by step (https://tomchentw.github.io/react-google-maps/basics/pop-up-window) and even if I can pass the property showInfo to true, the pop-up won't be displayed...
import React, {Component} from "react";
import "./Map.css";
import _ from "lodash";
import {withGoogleMap, GoogleMap, Marker, Polyline, InfoWindow} from "react-google-maps";
import withScriptjs from "react-google-maps/lib/async/withScriptjs";
import mapStyle from '../assets/map_style.json';
const GettingStartedGoogleMap = withScriptjs(withGoogleMap(props => (
<GoogleMap
ref={props.onMapLoad}
defaultZoom={11}
//defaultCenter={{lat: 48.853, lng: 2.35}}
defaultCenter={{lat: 33.5731, lng: -7.5898}}
defaultOptions={{
styles: mapStyle,
zoom: 12,
minZoom: 12,
maxZoom: 18
}}
onClick={props.onMapClick}
onResize={props.onResize}
onBoundsChanged={props.onBoundsChanged}
onCenterChanged={props.onCenterChanged}
>
{props.markers.map((marker, index) => (
<Marker
{...marker}
key={marker.id}
position={marker.position}
onClick={() => props.onMarkerClick(marker)}
>
{}
{marker.showInfo && (
<InfoWindow onCloseClick={() => props.onMarkerClose(marker)}>
<div>hello</div>
</InfoWindow>
)}
</Marker>
))}
{props.polylines.map((polyline, index) => (
<Polyline
{...polyline}
key={polyline.id}
path={polyline.coords}
options={polyline.options}
onRightClick={_.noop}
/>
))}
</GoogleMap>
)));
class Map extends Component {
constructor(props) {
super(props);
this.map = null;
this.state = {
allowedBounds: null,
lastValidCenter: null
};
this.onMapLoad = this.onMapLoad.bind(this);
this.onBoundsChanged = this.onBoundsChanged.bind(this);
this.onCenterChanged = this.onCenterChanged.bind(this);
}
onMapLoad(map) {
this.map = map;
this.setState({allowedBounds: new window.google.maps.LatLngBounds(
new window.google.maps.LatLng(33.5, -7.7),
new window.google.maps.LatLng(33.65, -7.45)
)});
this.setState({lastValidCenter: this.map.getCenter()});
}
onBoundsChanged() {
this.onBoundsChanged = _.noop;
this.props.onMapReady(this.map);
}
onCenterChanged() {
if (this.state.allowedBounds == null)
return;
if (this.state.allowedBounds.contains(this.map.getCenter())) {
// still within valid bounds, so save the last valid position
this.setState({lastValidCenter: this.map.getCenter()});
return;
}
// not valid anymore => return to last valid position
this.map.panTo(this.state.lastValidCenter);
}
handleMarkerClick(targetMarker) {
console.log(this.props.markers);
this.setState({
markers: this.props.markers.map(marker => {
if (marker === targetMarker) {
marker = {
...marker,
showInfo: true,
};
console.log(marker);
}
return marker;
}),
});
}
handleMarkerClose(targetMarker) {
this.setState({
markers: this.props.markers.map(marker => {
if (marker === targetMarker) {
return {
...marker,
showInfo: false,
};
}
return marker;
}),
});
}
handleMarkerClick = this.handleMarkerClick.bind(this);
handleMarkerClose = this.handleMarkerClose.bind(this);
render() {
return (
<section id="map" className={this.props.className}>
<GettingStartedGoogleMap
containerElement={
<div style={{height: `100%`}}/>
}
mapElement={
<div style={{height: `100%`}}/>
}
loadingElement={
<p>Loading...</p>
}
googleMapURL="https://maps.googleapis.com/maps/api/js?key=AIzaSyDGNmlXqmPTqSkJpC2DLEIaSL9X6azn2b8&libraries=places,geometry"
onMapLoad={this.onMapLoad}
onResize={() => console.log("resize")}
onMapClick={() => console.log(this.map)}
onMarkerClick={this.handleMarkerClick}
onMarkerClose={this.handleMarkerClose}
markers={this.props.markers}
polylines={this.props.polylines}
onBoundsChanged={this.onBoundsChanged}
onCenterChanged={this.onCenterChanged}
/>
</section>
);
}
}
export default Map;
So the marker returns this in my console :
Object {id: "t1_10", position: _.F, showInfo: true, icon: Object}
icon:Object
id:"t1_10"
position:_.F
showInfo:true
Thank you in advance !

Angular 2 HTTP GET with TypeScript google geocode service

I am new to angular2 and trying to find the coordinates(latitude,longitude) using the location.
here is my code,
GeoService.ts
import { Injectable } from '#angular/core';
import { Http } from '#angular/http';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/toPromise';
#Injectable()
export class GeoService {
constructor(private http: Http) { }
getLocation(term: string) {
return this.http.get('http://maps.google.com/maps/api/geocode/json?address=' + term + 'CA&sensor=false').map
((response) => response.json());
}
// tslint:disable-next-line:eofline
}
app.component.html
<!DOCTYPE HTML>
<h1> {{title}} </h1>
<input type="text" [(ngModel)]="location" />
<button (click)="findLocation($event)">Find location</button>
<sebm-google-map
[latitude]="lat"
[longitude]="lng"
[zoom]="zoom"
[disableDefaultUI]="false"
[zoomControl]="false"
(mapClick)="mapClicked($event)">
<sebm-google-map-marker
*ngFor="let m of markers; let i = index"
(markerClick)="clickedMarker(m.label, i)"
[latitude]="m.lat"
[longitude]="m.lng"
[label]="m.label"
[markerDraggable]="m.draggable"
(dragEnd)="markerDragEnd(m, $event)">
<sebm-google-map-info-window>
<strong>InfoWindow content</strong>
</sebm-google-map-info-window>
</sebm-google-map-marker>
<sebm-google-map-circle [latitude]="lat + 0.3" [longitude]="lng"
[radius]="5000"
[fillColor]="'red'"
[circleDraggable]="true"
[editable]="true">
</sebm-google-map-circle>
</sebm-google-map>
app.component.ts
import { Component } from '#angular/core';
import { GeoService } from './GeoService';
#Component({
selector: 'my-app',
moduleId: module.id,
templateUrl: `./app.component.html`,
styleUrls: ['/app.componenet.css'],
providers :[GeoService]
})
export class AppComponent {
title = 'Angular2 google map test';
lat: number = 51.673858;
lng: number = 7.815982;
zoom: number = 8;
markers: marker[] = [
{
lat: 51.673858,
lng: 7.815982,
label: 'A',
draggable: true
},
{
lat: 51.373858,
lng: 7.215982,
label: 'B',
draggable: false
},
{
lat: 51.723858,
lng: 7.895982,
label: 'C',
draggable: true
}
];
location: string;
findLocation(): void {
this.result= this.geoService.getLocation(this.location);
}
constructor(private geoService: GeoService) {
}
clickedMarker(label: string, index: number) {
}
mapClicked($event: MouseEvent) {
}
markerDragEnd(m: marker, $event: MouseEvent) {
console.log('dragEnd', m, $event);
}
}
// tslint:disable-next-line:class-name
interface marker {
lat: number;
lng: number;
label?: string;
draggable: boolean;
}
how to get the result in app.component.ts?
findLocation(): void {
this.result= this.geoService.getLocation(this.location);
}
Hopefully you are not still stuck on this. While this might no longer help you, hopefully it will help someone else. Here is what I did just now. First change the getLocation function to this. This is for the current Angular2 release.
getLocation(term: string):Promise<any> {
return this.http.get('http://maps.google.com/maps/api/geocode/json?address=' + term + 'CA&sensor=false')
.toPromise()
.then((response) => Promise.resolve(response.json()));
.catch((error) => Promise.resolve(error.json()));
}
And then in app.component.ts, change it to this.
findLocation(): void {
this.geoService.getLocation(this.location)
.then((response) => this.result = response.results[0])
.catch((error) => console.error(error));
}
I added some error control because that is always good to have. And I had a results array return inside response so clarify with the user which address they want if there is more than one returned.
angular 7.1.4 httpclient is used. getLocation returns obserable
location.service.ts renamed GeoService.ts
import { Injectable } from "#angular/core";
import { HttpClient } from "#angular/common/http";
import { Observable } from "rxjs";
#Injectable({
providedIn: "root"
})
export class LocationService {
constructor(private http: HttpClient) {}
getLocation(term: string): Observable<any> {
return this.http.get(
"http://maps.google.com/maps/api/geocode/json?address=" +
term +
"CA&sensor=false&key=API_KEY"
);
}
}
location.component.ts
/// <reference types="#types/googlemaps" />
import { Component, OnInit, AfterContentInit, ViewChild } from "#angular/core";
import { LocationService } from "../location.service";
declare let google: any;
#Component({
selector: "app-location",
templateUrl: "./location.component.html",
styleUrls: ["./location.component.scss"],
providers: [LocationService]
})
export class LocationComponent implements OnInit {
#ViewChild("gmap") gmapElement: any;
map: google.maps.Map;
latitude: number;
longitude: number;
marker: google.maps.Marker;
locationStr: string;
public result: any;
countMarkers = 0;
constructor(public geoService: LocationService) {}
ngOnInit() {
this.setCurrentPosition();
// tslint:disable-next-line:prefer-const
let mapProp = {
center: new google.maps.LatLng(0, 0),
zoom: 18,
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
};
this.map = new google.maps.Map(this.gmapElement.nativeElement, mapProp);
}
setCenter(e: any) {
e.preventDefault();
this.map.setCenter(new google.maps.LatLng(this.latitude, this.longitude));
}
setCurrentPosition() {
navigator.geolocation.getCurrentPosition(position => {
console.log("Set position", position.coords);
this.latitude = position.coords.latitude;
this.longitude = position.coords.longitude;
this.map.setCenter(new google.maps.LatLng(this.latitude, this.longitude));
const location = new google.maps.LatLng(this.latitude, this.longitude);
this.map.panTo(location);
if (!this.marker) {
this.marker = new google.maps.Marker({
position: location,
map: this.map,
draggable: false,
title: "You Loation!"
});
this.marker.setLabel("You");
this.marker.setMap(this.map);
} else {
this.marker.setPosition(location);
}
});
}
setMarker(label = ".") {
const location = new google.maps.LatLng(this.latitude, this.longitude);
this.map.panTo(location);
if (!this.marker) {
this.marker = new google.maps.Marker({
position: location,
map: this.map,
draggable: false,
title: "You Loation!"
});
this.marker.setLabel(label);
this.marker.setMap(this.map);
} else {
this.marker.setLabel(label);
this.marker.setPosition(location);
}
}
addMarker(label = "") {
const location = new google.maps.LatLng(this.latitude, this.longitude);
// this.map.panTo(location);
const newMarker = new google.maps.Marker({
position: location,
map: this.map,
draggable: false,
title: "You Loation!"
});
this.countMarkers++;
label = this.countMarkers.toString();
newMarker.setLabel(label);
newMarker.setMap(this.map);
}
findLocation(): void {
this.geoService
.getLocation(this.locationStr)
.subscribe(
(data: any) => (
(this.result = data.results[0].geometry.location),
console.log(data.results[0].geometry.location),
(this.latitude = data.results[0].geometry.location.lat),
(this.longitude = data.results[0].geometry.location.lng),
this.map.setCenter(
new google.maps.LatLng(this.latitude, this.longitude)
),
this.addMarker()
),
(err: any) => console.log(err),
() => console.log("All done getting location.")
);
}
}