Having problems rendering contents from ComponentDidMount to <View> - react-native

How do i go about this? I am trying to render the contents of Initial region, so that once the Application Loads it automatically gets the Longitude and Latitude of the Location and put on the screen.
I am just a bit confused as to what and how to go about it, My source code is given thus
import React, { Component } from 'react';
import { View, Text , StyleSheet, Dimensions } from 'react-native';
import MapView from 'react-native-maps';
export default class HomePage extends Component {
constructor(props) {
super(props);
}
componentDidMount(){
navigator.geolocation.getCurrentPosition((position)=>{
var lat = parseFloat(position.coords.latitude)
var long = parseFloat(position.coords.longitude)
var initialRegion ={
latitude: lat,
longitude: long,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}
this.setState({ initialRegion: initialRegion })
},
(error) => aalert(JSON.stringify(error)),
{
enableHighAccuracy: true, timeout: 20000, maximumAge: 1000
});
}
render() {
return (
<View style={styles.container}>
<MapView style={styles.map}
initialRegion={this.state.initialRegion}
showsUserLocation={true}>
</MapView>
</View>
);
}
}
const styles=StyleSheet.create({
container:{
flex: 1,
},mapContainer: {
flex: 1,
},
map: {
flex: 1,
width: Dimensions.get("window").width,
height: Dimensions.get("window").height,
}
});
Any candid advice as to how I can do something like that? Kindly assist.

I would guess the your map loads with no initialRegion as you are doing a request after the first render (componentDidMount) you may try to prevent the map from loading before you have the necessary information, I've also started your state on constructor. The code would look like this:
import React, { Component } from 'react';
import { View, Text , StyleSheet, Dimensions } from 'react-native';
import MapView from 'react-native-maps';
export default class HomePage extends Component {
constructor(props) {
super(props);
this.state = {
initialRegion: null
}
}
componentDidMount(){
navigator.geolocation.getCurrentPosition((position)=>{
var lat = parseFloat(position.coords.latitude)
var long = parseFloat(position.coords.longitude)
var initialRegion = {
latitude: lat,
longitude: long,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421
}
this.setState({ initialRegion: initialRegion })
},
(error) => aalert(JSON.stringify(error)),
{
enableHighAccuracy: true, timeout: 20000, maximumAge: 1000
});
}
render() {
return (
<View style={styles.container}>
{this.state.initialRegion !== null && (
<MapView style={styles.map}
initialRegion={this.state.initialRegion}
showsUserLocation={true} />
)}
</View>
);
}
}
Wish success on your project.

Related

Undefined is not an object in React native when rendering

I'm new to React and React native and am trying to retrieve data from an API and then render it but I seem to be running into problems.
I'm getting errors like:
undefined is not an object (evaluating 'attractions.map') in RenderPhotos_render
I may have jumped into React Native too early...So excuse my lack of knowledge!
import React, {Component} from 'react';
import {StyleSheet, View, ActivityIndicator} from 'react-native';
import MapView, {Marker} from 'react-native-maps';
import {connect} from 'react-redux';
const mapStateToProps = state => {
return {
attractions: state.attractions.attractions,
};
};
const mapDispatchToProps = dispatch => {
return {
GET_Attractions(callback) {
dispatch({type: 'attractions/GET_Attractions', callback});
},
};
};
export default connect(
mapStateToProps,
mapDispatchToProps,
)(
class Home extends Component {
state = {
loading: true,
};
componentDidMount = () => {
const callback = () => {
this.setState({
loading: false,
});
};
this.props.GET_Attractions(callback);
};
renderMapMarker = () => {
const {attractions} = this.props;
return attractions.map(marker => {
return (
<Marker
key={marker.caseId}
title={marker.caseName}
description="點擊查看詳細資料"
coordinate={{
latitude: marker.latitude,
longitude: marker.longitude,
}}
/>
);
});
};
render() {
if (this.state.loading) {
return (
<View style={styles.container}>
<ActivityIndicator />
</View>
);
} else {
return (
<View style={styles.container}>
<MapView
style={styles.mapView}
initialRegion={{
latitude: 24.149706,
longitude: 120.683813,
latitudeDelta: 8,
longitudeDelta: 8,
}}>
{this.renderMapMarker()}
</MapView>
</View>
);
}
}
},
);
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
mapView: {
width: '100%',
height: '100%',
},
});
By default attractions might be undefined so you can check to validate first then render if it has data to render like
render() {
if (this.state.loading) {
return (
...
);
} else {
return (
<View style={styles.container}>
<MapView
...
>
{this.props.attractions && this.renderMapMarker()} // and this
</MapView>
</View>
);
}
}
You are trying to use a prop "attractions" that is being populated from the reducer, so initially when your screen is being rendered the prop "attractions" will be undefined so you need to achieve this with the condition to make the error go away.
{attractions && this.renderMapMarker()}
Just add ? after attractions and it should work.
renderMapMarker = () => {
const {attractions} = this.props;
return attractions?.map(marker => {
return (
<Marker
key={marker.caseId}
title={marker.caseName}
description="點擊查看詳細資料"
coordinate={{
latitude: marker.latitude,
longitude: marker.longitude,
}}
/>
);
});
};

TypeError: null is not an object (evaluating 'this.state.initialPosition') - React Native

I am doing a RN project using Geolocation to get the current location, but I don't know what's wrong in this.
Here is my code:
import React, { Component } from 'react';
// Import required component
import { SafeAreaView, StyleSheet, Text, Alert, TouchableOpacity, Image, View } from 'react-native';
import { request, PERMISSIONS } from 'react-native-permissions';
// Import vector icons
import Icon from 'react-native-vector-icons/FontAwesome';
import MapView, { PROVIDER_GOOGLE, Platform, Marker, Callout, Circle } from 'react-native-maps';
import coordinate from '../../api/binLocationData';
import Geolocation from '#react-native-community/geolocation';
export class Home extends Component {
componentDidMount() {
this.requestLocationPermission();
}
requestLocationPermission = async () => {
if (Platform.OS === 'IOS') {
var response = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
console.log('IOS: ' + response);
if (response === 'granted') {
this.locateCurrentPosition();
}
} else {
var response = await request(PERMISSIONS.ANDROID.LOCATION_WHEN_IN_USE);
console.log('Android: ' + response);
if (response === 'granted') {
this.locateCurrentPosition();
}
}
};
locateCurrentPosition = () => {
Geolocation.getCurrentPosition(
(position) => {
console.log(JSON.stringify(position));
let initialPosition = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: 0.05,
longitudeDelta: 0.05,
};
this.setState({ initialPosition });
},
(error) => Alert.alert(error.message),
{ enableHighAccuracy: true, timeout: 1000, maximumAge: 1000 },
);
};
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<MapView
provider={PROVIDER_GOOGLE}
ref={(map) => (this._map = map)}
showsUserLocation={true}
style={styles.maps}
initialRegion={this.state.initialPosition}
// initialRegion={{
// latitude: 16.0599,
// longitude: 108.2438,
// latitudeDelta: 0.05,
// longitudeDelta: 0.05,
// }}
>
<Circle
radius={1000}
center={{ latitude: 16.0599, longitude: 108.2438 }}
fillColor={'rgba(51,150,152,0.3)'}
/>
<Marker coordinate={{ latitude: 16.0599, longitude: 108.2438 }}>
<Callout>
<Text>Bin 1</Text>
</Callout>
{/* <Image source={require('./src/assets/icons/bin.png')} /> */}
</Marker>
{coordinate.map((marker) => (
<Marker
key={marker.id}
coordinate={{ latitude: marker.latitude, longitude: marker.longitude }}
title={marker.name}
/>
))}
</MapView>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
maps: {
...StyleSheet.absoluteFillObject,
},
});
export default Home;
And the debugging show:
TypeError: null is not an object (evaluating 'this.state.initialPosition')
How can I fix it?
You forget to initialise state. You should add this to your class component:
constructor(props) {
this.state = {
latitude: 0,
longitude: 0,
latitudeDelta: 0,
longitudeDelta: 0,
};
}
This should works:
import React, { Component } from "react";
// Import required component
import {
SafeAreaView,
StyleSheet,
Text,
Alert,
TouchableOpacity,
Image,
View,
} from "react-native";
import { request, PERMISSIONS } from "react-native-permissions";
// Import vector icons
import Icon from "react-native-vector-icons/FontAwesome";
import MapView, {
PROVIDER_GOOGLE,
Platform,
Marker,
Callout,
Circle,
} from "react-native-maps";
import coordinate from "../../api/binLocationData";
import Geolocation from "#react-native-community/geolocation";
export class Home extends Component {
constructor(props) {
this.state = {
latitude: 0,
longitude: 0,
latitudeDelta: 0,
longitudeDelta: 0,
};
}
componentDidMount() {
this.requestLocationPermission();
}
requestLocationPermission = async () => {
if (Platform.OS === "IOS") {
var response = await request(PERMISSIONS.IOS.LOCATION_WHEN_IN_USE);
console.log("IOS: " + response);
if (response === "granted") {
this.locateCurrentPosition();
}
} else {
var response = await request(PERMISSIONS.ANDROID.LOCATION_WHEN_IN_USE);
console.log("Android: " + response);
if (response === "granted") {
this.locateCurrentPosition();
}
}
};
locateCurrentPosition = () => {
Geolocation.getCurrentPosition(
(position) => {
console.log(JSON.stringify(position));
let initialPosition = {
latitude: position.coords.latitude,
longitude: position.coords.longitude,
latitudeDelta: 0.05,
longitudeDelta: 0.05,
};
this.setState({
latitude: initialPosition.latitude,
longitude: initialPosition.longitude,
latitudeDelta: initialPosition.latitudeDelta,
longitudeDelta: initialPosition.longitudeDelta,
});
},
(error) => Alert.alert(error.message),
{ enableHighAccuracy: true, timeout: 1000, maximumAge: 1000 }
);
};
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={{ flex: 1 }}>
<MapView
provider={PROVIDER_GOOGLE}
ref={(map) => (this._map = map)}
showsUserLocation={true}
style={styles.maps}
initialRegion={this.state.initialPosition}
// initialRegion={{
// latitude: 16.0599,
// longitude: 108.2438,
// latitudeDelta: 0.05,
// longitudeDelta: 0.05,
// }}
>
<Circle
radius={1000}
center={{ latitude: 16.0599, longitude: 108.2438 }}
fillColor={"rgba(51,150,152,0.3)"}
/>
<Marker coordinate={{ latitude: 16.0599, longitude: 108.2438 }}>
<Callout>
<Text>Bin 1</Text>
</Callout>
{/* <Image source={require('./src/assets/icons/bin.png')} /> */}
</Marker>
{coordinate.map((marker) => (
<Marker
key={marker.id}
coordinate={{
latitude: marker.latitude,
longitude: marker.longitude,
}}
title={marker.name}
/>
))}
</MapView>
</View>
</SafeAreaView>
);
}
}
const styles = StyleSheet.create({
maps: {
...StyleSheet.absoluteFillObject,
},
});
export default Home;

How to solve: Undefined Promise Rejection (id:0) type error with user location map?

My position is in Vietnam but the device doesn't display the permission asking when I navigate to this screen
Here's the error
I tried to use react-native-maps and import permissions, location from expo-permissions + expo-location
Do I have to catch the error and how to do it?
Also I'm using my real device
This is the code
import React from 'react';
import {
View,
Text,
StyleSheet,
PermissionsAndroid,
} from 'react-native'
import MapView from 'react-native-maps';
import {Permissions} from 'expo-permissions';
import {Location} from 'expo-location'
class MapViewScreen extends React.Component {
constructor(props){
super(props);
this.state={
region:{
latitude: 37.78825,
longitude: -122.4324,
latitudeDelta: 0.922,
longitudeDelta: 0.0421,
}
}
this._requestUserLocationPermission();
}
_requestUserLocationPermission = async () => {
const { status } = await Permissions.askAsync(Permissions.LOCATION);
if(status !== 'granted'){
alert('Please enable your location!')
}
let location = await Location.getCurrentPositionAsunc({enabledHighAccuracy: true})
let region = {
latitude: location.coords.latitude,
longitude: location.coords.longitude,
latitudeDelta: 0.045,
longitudeDelta: 0.045
}
}
render(){
return(
<View style={styles.container}>
<MapView
initialRegion={this.state.region}
showsCompass={true}
showsUserLocation={true}
rotateEnabled={false}
style={{flex: 1}}
/>
</View>
);
}
}
export default MapViewScreen;
const styles = StyleSheet.create({
container:{
flex: 1,
backgroundColor: '#fff',
}
})
I have successfully fixed the problem. By changing initialRegion to region prop in react-native-maps, the screen is able now to show my device location right after I enter the map screen. Thanks all for your help

React-Native-Maps Error (Super expression must either be null or a function)

Can anyone help me with this error?
I learn and copy the code from a YouTube tutorial about React-Native-Maps for displaying current location. Link: https://www.youtube.com/watch?v=MqLC0kOqrwk
The error is: Super expression must either be null or a function
I am using latest version of React-Native-Maps
React-Native-Maps Version :"^0.22.1",
This is my code.
import React from 'react';
import {
AppRegistry,
Component,
StyleSheet,
View,
Text,
screen,
Dimensions,
TouchableOpacity,
Platform,
} from 'react-native';
import MapView from 'react-native-maps';
import Strings from '../utils/Strings';
var styles = require('../../assets/files/Styles');
const {height, width} = Dimensions.get('window');
const SCREEN_HEIGHT = height
const SCREEN_WIDTH = width
const ASPECT_RATIO = width / height
const LATITUDE_DELTA = 0.00922;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;
export default class Track extends Component {
static navigationOptions = {
title: `${Strings.ST6}`,
};
constructor(props) {
super(props)
this.state = {
initialPosition: {
latitude: 0,
longitude: 0,
latitudeDelta: 0,
longitudeDelta: 0
},
markerPosition: {
latitude: 0,
longitude: 0
}
}
}
watchID = null
componentDidMount(){
navigator.geolocation.getCurrentPosition((position) => {
var lat = parseFloat(position.coords.latitude)
var long = parseFloat(position.coords.longitude)
var initialRegion = {
latitude: lat,
longitude: long,
latitudeDelta: LATITUDE_DELTA,
longitudeDelta: LONGTITUDE_DELTA
}
this.getState({initialPosition: initialRegion})
this.getState({markerPosition: initialRegion})
},
(error) => alert(JSON.stringify(error)),
{enableHighAccuracy: true, timeout: 20000, maximumAge: 1000})
this.watchID = navigator.geolocation.watchPosition((position) => {
var lat = parseFloat(position.coords.latitude)
var long = parseFloat(position,coords,longitude)
var lastRegion = {
latitude: lat,
longitude: long,
longitudeDelta: LONGTITUDE_DELTA,
latitudeDelta: LATITUDE_DELTA
}
this.setState({initialPosition: lastRegion})
this.setState({markerPosition: lastRegion})
})
}
componentWillUnmount() {
navigator.geolocation.clearWatch(this.watchID)
}
render() {
return(
<View style={style.container}>
<MapView
style={styles.map}
region={this.state.initialPosition}>
<MapView.Marker>
coordinate={this.state.markerPosition}
<View Style={styles.radius}>
<View Style={styles.marker}>
</View>
</View>
</MapView.Marker>
</MapView>
</View>
);
}
}
I guess the error is somewhere around
constructor(props) {
super(props)
But I don't see a error here, the super should be fine, the result is same even I remove the (props).
On your code class Track extends Component you forget to call the react properties. please change your code to be class Track extends React.Component.
Because you just call the Component, and react doesn't know where 'Component' comes from

React Native Maps animate to bearing after initial render

I am trying to call a method on the map right after the component first renders. In this case this.map is undefined, but shouldn't it be set by the ref? How do I get a reference to the MapView in the componentDidMount method?
import React from 'react';
import { MapView } from 'expo';
export default class Map extends React.Component {
componentDidMount() {
this.map.animateToBearing(25)
}
render() {
return (
<MapView
ref={ref => { this.map = ref }}
style={{ flex: 1 }}
mapType="satellite"
initialRegion={{
latitude: 39.2741004,
longitude: -76.6502307,
latitudeDelta: 0.002,
longitudeDelta: 0.001,
}}
/>
);
}
}
Looking at this Github issue, you probably have to use onLayout instead of componentDidMount.
For example:
<MapView
ref={ref => { this.map = ref }}
onLayout={() => this.map.animateToBearing(25)}
....
/>
const [heading, setHeading] = useState(0);
const cameraView = {
center: {
latitude: lat,
longitude: lng,
},
pitch: 10,
heading: heading,
altitude: 1,
zoom: 15
};
let getHeading = () => {
Location.watchHeadingAsync(value => {
setHeading(value.magHeading)
});
};
useEffect(()=>{
initialLocation();
getHeading();
}, [])
By using watchHeadingAsync you can update the heading constantly.