React-simple-map "Unexpected token < in JSON at position 0" - json

I would like to use react-simple-map for my project in react.
I used the example on github to try to display a simple map :
import React, { Component } from "react"
import {
ComposableMap,
ZoomableGroup,
Geographies,
Geography,
} from "react-simple-maps"
const wrapperStyles = {
width: "100%",
maxWidth: 980,
margin: "0 auto",
}
class BasicMap extends Component {
render() {
return (
<div style={wrapperStyles}>
<ComposableMap
projectionConfig={{
scale: 205,
rotation: [-11,0,0],
}}
width={980}
height={551}
style={{
width: "100%",
height: "auto",
}}
>
<ZoomableGroup center={[0,20]} disablePanning>
<Geographies geography="/static/world-50m.json">
{(geographies, projection) => geographies.map((geography, i) => geography.id !== "ATA" && (
<Geography
key={i}
geography={geography}
projection={projection}
style={{
default: {
fill: "#ECEFF1",
stroke: "#607D8B",
strokeWidth: 0.75,
outline: "none",
},
hover: {
fill: "#607D8B",
stroke: "#607D8B",
strokeWidth: 0.75,
outline: "none",
},
pressed: {
fill: "#FF5722",
stroke: "#607D8B",
strokeWidth: 0.75,
outline: "none",
},
}}
/>
))}
</Geographies>
</ZoomableGroup>
</ComposableMap>
</div>
)
}
}
export default BasicMap
But, I have the error message "Unexpected token < in JSON at position 0" in the console. I kept exactly the same folders. The only error message is this.
If you have an idea about a map in react, with which i would be able to color each country with different color depending on certains criteria...
Thank you in advance.

I faced same problem. If you place world-50m.json inside src folder, react cannot load it with get request - it tries to load it from http://localhost:3000/static/world-50m.json. In my case it returns custom 404 HTML page -> and that is why error "Unexpected token < in JSON at position 0" occurs.
Solution is to move json with map inside react public folder and than it starts to work.

Related

Struggling to get framer-motion's exit animation working. [React.JS]

RenderPokemonInfo.js:
const RenderPokemonInfo = (props) => {
const pokemon = props.pokemonToUse;
const pokemonCurrentTypes = [];
let gradientString = "";
const animateFromTop = {
before: {
y: '-100vh',
opacity: 0,
},
onScreen: {
y: '0',
opacity: 1,
},
after: {
y: '100vh',
opacity: 0,
}
}
pokemon.types.map((typeData) => {
pokemonCurrentTypes.push(typeData.type.name);
})
if(pokemonCurrentTypes.length === 1) {
gradientString = getGradient({typeString: pokemonCurrentTypes[0]});
} else {
gradientString = getGradient({typeString: pokemonCurrentTypes[0]}) + ', ' + getGradient({typeString: pokemonCurrentTypes[1]});
}
return (
<>
<motion.div variants={animateFromTop} initial='before' animate='onScreen' exit='after' key={pokemon.name}>
<div style={{
position: 'absolute',
width: '420px',
height: '640px',
left: '75%',
top: '30px',
transform: 'translateX(-50%)',
backgroundImage: 'linear-gradient(225deg, ' + gradientString + ')',
boxShadow: '0 20px 20px 0 rgba(0,0,0,0.2)',
borderRadius: '30px'}} key={'poke-pic-' + pokemon.name}>
<fieldset className="poke-height-fieldset">
<legend style={{position: 'absolute', left: '10px'}}>{pokemon.height * 10} cm</legend>
<div className='big-poke-img-container'>
<img src={'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/dream-world/' + pokemon.id + '.svg'} className='big-poke-img'></img>
</div>
</fieldset>
<div className='poke-type-container'>
{pokemon.types.map((type) => <PokemonTypeButton typeString={type.type.name} isButton={false} key={type.type.name}/>)}
</div>
</div>
</motion.div>
</>
)
}
export default RenderPokemonInfo;
Part of my App.js that calls RenderPokemonInfo:
<div className='content-container'>
{(pokemon.length === 0) ? (
<p>Pick a pokemon!</p>
) : (
<AnimatePresence exitBeforeEnter={true}>
<RenderPokemonInfo pokemonToUse={pokemon} key={pokemon.name}/>
</AnimatePresence>
)}
</div>
When coming on screen the animations are fine, but when it leaves it just vanishes, no animation. I've seen on framer-motion's docs that you should put set the initial prop to false in AnimatePresence but when I do that it doesn't have an enter animation or an exit animation... am I doing something wrong here?
Is this entire component getting removed? If so, then you'll need to move the AnimatePresence tag up into the parent component. AnimatePresence watches for children getting removed from the DOM and runs the exit animation before removing them. If you have the AnimatePresence tag inside the component that gets removed, then it has no chance to run the exit animation, because the AnimatePresence tag is gone immediately along with the rest of the component.
You'd need something more like this (in your parent component):
<AnimatePresence>
{ pokemons.map(pokemon => <PokemonCard key={pokemon.name} />) }
</AnimatePresence>
And your PokemonCard would return the motion.div you show above (without the AnimatePresence tag)
This all came down to me not fully understanding how React uses keys. I used React.Child.toArray() to wrap everything I rendered from a map, this makes React give everything a unique key.

expo - react native - webview - html5 - obeject tag - issue

I tried to use Expo - Webview to display an HTML5 content(.html) using <object> but it does not work.
The same html5 content is working perfectly in a regular webpage.
Can somebody guide with a simple example to achieve the above mentioned scenario ?
Here is the code,
I tried both react-native-render-html and webview, nothing works.
import React, { Component } from 'react';
import { withNavigation } from '#react-navigation/compat';
import { StyleSheet, Dimensions, Image, TouchableWithoutFeedback,ScrollView } from 'react-native';
import { Block, Text, theme } from 'galio-framework';
import HTML from 'react-native-render-html';
import Constants from 'expo-constants';
import materialTheme from '../constants/Theme';
import { heightPercentageToDP } from 'react-native-responsive-screen';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
import {WebView} from 'react-native-webview';
import { Video } from 'expo-av';
class CourseDetail extends React.Component {
render() {
const imageStyles = [styles.image, styles.normalImage];
const {navigation,route}= this.props;
const Course = route.params.course;
const imageUrl = route.params.imageUrl;
const videoUrl = route.params.videoUrl;
return (
<ScrollView
showsVerticalScrollIndicator={false}
contentContainerStyle={styles.catalogItems}>
<Block flex style={[styles.article]}>
<Text size={30} style={styles.CourseTitle}>{Course.Title}</Text>
<HTML containerStyle={styles.courseWrap } html={ '<object type="text/html" data="https://domainname.com/story_html5.html" ></object>'} />
<WebView source={{ uri: 'https://domainname.com/story_html5.html' }} />
</Block>
</ScrollView>
);
}
}
export default withNavigation(CourseDetail);
const styles = StyleSheet.create({
article:{
backgroundColor: theme.COLORS.WHITE,
padding:hp('3%')
},
content: {
flex:1,
},
CourseTitle:{
flex: 1,
flexWrap: 'wrap',
paddingBottom: 10,
paddingTop:5,
fontFamily:'manifa-regular',
color:'#333333',
},
imageContainer: {
elevation: 1,
},
shadow: {
shadowColor: 'rgba(0,51,160,0.15)',
shadowOffset: { width: 0, height: 5 },
shadowRadius:15,
shadowOpacity: 1,
elevation:15,
},
image: {
borderRadius: 3,
marginHorizontal: wp('1%'),
marginTop: hp('5%'),
backgroundColor:'#84BD00',
},
normalImage: {
height:hp('25%'),
width:'auto',
// / marginTop:hp('3.3%'),
marginHorizontal: 0,
marginRight: wp('0%'),
marginLeft:wp('0%'),
marginTop:hp('3 %'),
marginBottom:hp('1%'),
flex: 1,
flexDirection: 'row',
padding:0
},
courseWrap:
{
marginVertical:10,
width:'100%',
height:hp('50%'),
backgroundColor:'red'
},
description:
{
marginTop:10
}
});

React Native: How to use Webview to read video post from Wordpress?

I am quite new in react native. I am using expo and trying to read data from WordPress. But the problem appeared when the post contains a video.
The video is running well but the video size showed inside the is bigger than the screen size.
I have tried scalesPageToFit={true}. However, it did not work for me.
Is there any way to solve this issue?
const styles = {
featuredImage: {
backgroundColor: 'black',
width: window.width,
height: 200
},
title: {
fontFamily: 'roboto-slab-regular',
fontSize: 20,
lineHeight: 22,
marginTop: 16,
marginHorizontal: 16
},
content: {
flex: 1,
height: 400,
alignItems: 'center'
},
meta: {
marginTop: 16,
marginHorizontal: 16,
}
}
export default class Post extends Component {
webview = null;
constructor(props) {
super(props);
this.state = {
tamanho: 122,
post: props.post,
scalesPageToFit: true,
};
}
_postMessage = ( ) => {
this.webview.postMessage( "Hello" );
console.log( "Posted message" );
scalesPageToFit=true
}
_receivedMessage = ( e ) => {
console.log("Received message");
this.setState( { tamanho: parseInt(e.nativeEvent.data)} );
scalesPageToFit=true
}
componentDidMount() {
this._postMessage();
}
render() {
let post = this.state.post;
let HTML ='<html>' +
'<head>' +
'<title></title>' +
'</head>' +
'<body>' +
post.content.rendered +
'</body>' +
'</html>';
let javascript = 'window.location.hash = 1;' +
'document.title = document.body.scrollHeight;' +
'window.postMessage( document.body.scrollHeight );';
return (
<View>
<PostImage post={post} style={styles.featuredImage} showEmpty />
<Text style={styles.title}>{entities.decode(post.title.rendered)}</Text>
<PostMeta style={styles.meta} post={post} />
<WebView
scrollEnabled={false}
ref={webview => { this.webview = webview; }}
injectedJavaScript={javascript}
javaScriptEnabled={true}
javaScriptEnabledAndroid={true}
onMessage={this._receivedMessage}
scalesPageToFit={true}
allowsInlineMediaPlayback={true}
decelerationRate="normal"
style={styles.content}
automaticallyAdjustContentInsets={false}
domStorageEnabled={true}
startInLoadingState={true}
source={{html: HTML}}
/>
</View>
);
}
}
Add the width property to fit the webview to device's screen to the styles in your react-native project.
import { Dimensions } from 'react-native';
const deviceWidth = Dimensions.get('window').width;
Add this below snippet in styles
content: {
flex: 1,
backgroundColor: 'yellow',
width: deviceWidth,
height: 400//deviceHeight
}

How to get the address from google maps autocomplete in React Native

I am using react-native-google-places-autocomplete to select a location. I want to extract the location selected and use it in other component.
How can I save the address
This is my code
import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};
export default class google extends Component {
render(){
return (
<View style={styles.container}>
<View style={styles.top}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);
this.setState(
{
address: data.description, // selected address
coordinates: `${details.geometry.location.lat},${details.geometry.location.lng}` // selected coordinates
}
);
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaS#################',
language: 'es', // language of the results
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
types: 'food'
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={[homePlace, workPlace]}
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
renderRightButton={() => <Text>Custom text after the input</Text>}
/>
</View>
<View style={styles.container2}>
<Text>
hola {this.setState.address}
</Text>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
width: '100%',
height: '100%',
},
welcome: {
fontSize: 40,
textAlign: 'center',
margin: 10,
color:'black',
},
instructions: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
},
top: {
height: '50%',
justifyContent: 'center',
alignItems: 'center',
},
container2: {
height:'75%',
justifyContent: 'center',
},
buttonContainer: {
alignItems: 'center',
backgroundColor: 'rgba(255, 255,255, 0.5)',
padding: 1,
margin: 50,
borderRadius: 25,
borderWidth: 2,
borderColor: '#0B0B3B'
},
textoboton: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
fontSize: 12
},
})
I've been also using another library with some differences
app.js
import React,{Component} from 'react';
import { Constants } from 'expo';
import Icon from 'react-native-vector-icons/FontAwesome';
import { View, Image, Text, StyleSheet, AsyncStorage, Button,ScrollView, TextInput, ActivityIndicator } from 'react-native';
import {
NavigationActions
} from 'react-navigation';
import { GoogleAutoComplete } from 'react-native-google-autocomplete';
import {Card, Input} from "react-native-elements";
import LocationItem from './locationItem';
export default class App extends React.Component {
state={
datos:[],
}
componentDidMount(){
this._loadedinitialstate().done();
}
_loadedinitialstate =async() => {
AsyncStorage.getItem('datos');
}
render() {
return (
<View style={styles.container}>
<GoogleAutoComplete apiKey={'AIzaSyB2HyNTBm1sQJYJkwOOUA1LXRHAKh4gmjU'} debounce={20} minLength={2} getDefaultValue={() => ''} onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);}} returnKeyType={'default'} fetchDetails={true}
>
{({
locationResults,
isSearching,
clearSearchs,
datos,
handleTextChange
}) => (
<React.Fragment>
<View style={styles.inputWrapper}>
<Input
style={styles.textInput}
placeholder="Ingresa tu direccion"
onChangeText={(datos) => this.setState({datos})}
value={datos}
/>
</View>
{isSearching && <ActivityIndicator size="large" color="red" />}
<ScrollView>
{locationResults.map(el => (
<LocationItem
{...el}
key={el.id}
/>
))}
</ScrollView>
</React.Fragment>
)}
</GoogleAutoComplete>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
textInput: {
height: 40,
width: 300,
borderWidth: 1,
paddingHorizontal: 16,
},
inputWrapper: {
marginTop: 80,
flexDirection: 'row'
},
});
locationitem.js
import React, { PureComponent } from 'react';
import { View, Alert, Text, StyleSheet, TouchableOpacity, AsyncStorage} from 'react-native';
class LocationItem extends PureComponent {
constructor(props) {
super(props);
this.state = {datos:''};
}
_handlePress = () => {
AsyncStorage.setItem('datos',datos)
}
render() {
return (
<TouchableOpacity style={styles.root} onPress={this._handlePress} >
<Text value={this.state.datos}> {this.props.description} </Text>
</TouchableOpacity>
);
}
}
const styles = StyleSheet.create({
root: {
height: 40,
borderBottomWidth: StyleSheet.hairlineWidth,
justifyContent: 'center'
}
})
export default LocationItem;
The source of both codes is here react-native-google-places-autocomplete enter link description here
Which code will be easy to use, and How can I solve my Issue (get the address) ??
Any Answer will be Helpful
first install
npm i react-native-google-places-autocomplete
then
import React from 'react';
import { View, Image } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};
const GooglePlacesInput = () => {
return (
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
listViewDisplayed='auto' // true/false/undefined
fetchDetails={true}
renderDescription={row => row.description} // custom description render
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
console.log(data, details);
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'YOUR API KEY',
language: 'en', // language of the results
types: '(cities)' // default: 'geocode'
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
}}
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
types: 'food'
}}
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
predefinedPlaces={[homePlace, workPlace]}
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
renderLeftButton={() => <Image source={require('path/custom/left-icon')} />}
renderRightButton={() => <Text>Custom text after the input</Text>}
/>
);
}
After a long journey, these steps helped me solve the problem.
1) Install npm install react-native-google-places-autocomplete --save.
2) Then use this code below, as an element in your component.
<GooglePlacesAutocomplete
query={{
key: "GOOGLE_PLACES_API_KEY",
language: "en", // language of the results
}}
onPress={(data, details = null) => {
console.log(details);
console.log(data);
console.log("data.description",data.description.split(','));
}}
onFail={(error) => console.error(error)}
listViewDisplayed="false"
requestUrl={{
url:
"https://cors-
anywhere.herokuapp.com/https://maps.googleapis.com/maps/api",
useOnPlatform: "web",
}} // this in only required for use on the web. See https://git.io/JflFv
more for details.
styles={{
textInputContainer: {
backgroundColor: "rgba(0,0,0,0)",
borderTopWidth: 0,
borderBottomWidth: 0,
},
textInput: {
marginLeft: 0,
marginRight: 0,
height: 38,
color: "#5d5d5d",
fontSize: 16,
},
predefinedPlacesDescription: {
color: "#1faadb",
},
}}
/>
3) You may have the same problem that i had, which the list disappears when i try to select result. However, this is the action that solved this problem for me.
Commenting out onBlur on node_modules. path: "..\node_modules\react-native-google-places-autocomplete\GooglePlacesAutocomplete.js".
...
onFocus={onFocus ? () => {this._onFocus(); onFocus()} : this._onFocus}
// onBlur={this._onBlur}
underlineColorAndroid={this.props.underlineColorAndroid}
...
4) For saving the address you can check the console.log in the code, and then use setState or something like this.
5) For more information and options of these element check out this repository:
https://github.com/FaridSafi/react-native-google-places-autocomplete.
hope this will help for you :)
First of all, I used listViewDisplayed={false} because otherwise the list view get stuck with the results, and even on location press the list doesn't closes.
Second, to answer your question: The results are in the onPress function of GooglePlacesAutocomplete, you can update the state with the chosen location and then use it where ever you want in your component:
onPress={(data, details = null) => {
this.setState({
latitude: details.geometry.location.lat,
longitude: details.geometry.location.lng,
moveToUserLocation: true
});
this._gotoLocation();
}
}
As i wrote it, onPress also trigger the function that moves the map to display the new location.
import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
export default class google extends Component {
constructor(props) {
super(props);
this.state = {
address:null,
lat:null,
lng:null,
}
}
getAdd(data){
console.log("add",data);
this.setState(
{
address: data.formatted_address, // selected address
lat: data.geometry.location.lat,// selected coordinates latitude
lng:data.geometry.location.lng, // selected coordinates longitute
}
);
console.log("this.state.address",this.state.address); ///to console address
console.log("this.state.coordinates",this.state.lat,this.state.lng); /// to console coordinates
}
render(){
return (
<View style={styles.container}>
<View style={styles.top}>
<GooglePlacesAutocomplete
placeholder='Search'
minLength={2} // minimum length of text to search
autoFocus={false}
fetchDetails={true}
returnKeyType={'default'}
onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
var data = details;
this.getAdd(data);
}}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaS#################',
language: 'en',
types: 'geocode', // default: 'geocode'
}}
listViewDisplayed={this.state.showPlacesList}
textInputProps={{
onFocus: () => this.setState({ showPlacesList: true }),
onBlur: () => this.setState({ showPlacesList: false }),
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
currentLocationLabel="Current location"
nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
// predefinedPlaces={[]}
predefinedPlacesAlwaysVisible={true}
/>
</View>
{ this.state.address !=null ?(
<View style={styles.container2}>
<Text>
Address: {this.state.address}
</Text>
</View>
):null }
</View>
);
}
}
const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
},
welcome: {
fontSize: 40,
textAlign: 'center',
margin: 10,
color:'black',
},
instructions: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
},
top: {
height: '50%',
justifyContent: 'center',
alignItems: 'center',
},
container2: {
height:'75%',
justifyContent: 'center',
},
buttonContainer: {
alignItems: 'center',
backgroundColor: 'rgba(255, 255,255, 0.5)',
padding: 1,
margin: 50,
borderRadius: 25,
borderWidth: 2,
borderColor: '#0B0B3B'
},
textoboton: {
textAlign: 'center',
color: 'black',
marginBottom: 5,
fontSize: 12
},
})

react-google-maps Customize Marker Icon

Currently, I have rendered the map component into a reusables component successfully using InfoModal to show an icon, however, the standard red Google Map icon I have not modified, and I want to create a custom icon myself. I'm not sure with ES6 and JSX syntax what I need to do. I looked into react-google-maps Issues and attempted to see if there were any current or updated material anywhere for how to do this (which is probably simple), but I'm not sure if react-google-maps has something for custom marker creation in addons or the correct format.
import React, { Component } from 'react'
import { withGoogleMap, GoogleMap, Marker, InfoWindow } from 'react-google-maps'
import { DEFAULT_MARKER } from '../../constants/mapDefaults'
const MapGoogleMap = withGoogleMap(props => (
<GoogleMap
defaultZoom={16}
center={props.center}
>
{props.markers.map((marker, index) => (
<Marker
key={index}
position={marker.position}
onClick={() => props.onMarkerClick(marker)}
>
{marker.showInfo && (
<InfoWindow onCloseClick={() => props.onMarkerClose(marker)}>
<div>{marker.infoContent}</div>
</InfoWindow>
)}
</Marker>
))}
</GoogleMap>
))
export default class Map extends Component {
state = {
center: {
lat: 28.3421135,
lng: -80.6149092
},
markers: [
{
position: new google.maps.LatLng(28.3431165, -80.6135908),
showInfo: false,
infoContent: (
<svg
id="Layer_1"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
>
<path
d="M3.5 0c-1.7 0-3 1.6-3 3.5 0 1.7 1 3 2.3 3.4l-.5 8c0
.6.4 1 1 1h.5c.5 0 1-.4 1-1L4 7C5.5 6.4 6.5 5 6.5
3.4c0-2-1.3-3.5-3-3.5zm10 0l-.8 5h-.6l-.3-5h-.4L11
5H10l-.8-5H9v6.5c0 .3.2.5.5.5h1.3l-.5 8c0 .6.4 1 1 1h.4c.6 0
1-.4 1-1l-.5-8h1.3c.3 0 .5-.2.5-.5V0h-.4z"
/>
</svg>
)
}, DEFAULT_MARKER
]
}
handleMarkerClick = this.handleMarkerClick.bind(this);
handleMarkerClose = this.handleMarkerClose.bind(this);
handleMarkerClick (targetMarker) {
this.setState({
markers: this.state.markers.map(marker => {
if (marker === targetMarker) {
return {
...marker,
showInfo: true
}
}
return marker
})
})
}
handleMarkerClose (targetMarker) {
this.setState({
markers: this.state.markers.map(marker => {
if (marker === targetMarker) {
return {
...marker,
showInfo: false
}
}
return marker
})
})
}
render () {
return (
<MapGoogleMap
containerElement={
<div style={{ height: `500px` }} />
}
mapElement={
<div style={{ height: `500px` }} />
}
center={this.state.center}
markers={this.state.markers}
onMarkerClick={this.handleMarkerClick}
onMarkerClose={this.handleMarkerClose}
/>
)
}
}
this is how I fixed that
let iconMarker = new window.google.maps.MarkerImage(
"https://lh3.googleusercontent.com/bECXZ2YW3j0yIEBVo92ECVqlnlbX9ldYNGrCe0Kr4VGPq-vJ9Xncwvl16uvosukVXPfV=w300",
null, /* size is determined at runtime */
null, /* origin is 0,0 */
null, /* anchor is bottom center of the scaled image */
new window.google.maps.Size(32, 32)
);
return(
<Marker
icon={iconMarker}
key={marker.id}
onClick={onClick}
position={{ lat: parseInt(marker.latitude), lng: parseInt(marker.longitude)}}>
{props.selectedMarker === marker &&
<InfoWindow>
<div style={{'color':'black'}}>
Shop {marker.name} {stretTexte}
</div>
</InfoWindow>}
</Marker>
)
Franklin you can use in react google maps. It has two advantages that takes it to use over info window or simple Marker component. We have Icon options to customize our marker. We have div elements that are fully customizable. You just pass icon url. LabelStyling is optional. Feel free to ask any question.
import { MarkerWithLabel } from 'react-google-maps/lib/components/addons/MarkerWithLabel';
var markerStyling= {
clear: "both", display: "inline-block", backgroundColor: "#00921A", fontWeight: '500',
color: "#FFFFFF", boxShadow: "0 6px 8px 0 rgba(63,63,63,0.11)", borderRadius: "23px",
padding: "8px 16px", whiteSpace: "nowrap", width: "160px", textAlign: "center"
};
<MarkerWithLabel
key={i}
position={marker.position}
labelAnchor={new google.maps.Point(75, 90)}
labelStyle={markerStyling}
icon={{
url: '/build/icon/markPin.svg',
anchor: new google.maps.Point(5, 58),
}}
>
<div>
<p> My Marker </p>
</div>
</MarkerWithLabel>
The Marker spread operator was missing above key={index}. This is the correct code. The icon itself is defined in another file called mapDefaults.js if anyone comes across this issue don't hesitate to reach out to me.
<Marker
{...marker}
key={index}
position={marker.position}
onClick={() => props.onMarkerClick(marker)}
>