Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Leaflet TypeError: Cannot read property 'lat' of null

I'm working on a map that asks for permissions for the users location. Than if the location is allowed it finds the users location and then changes the coords of the leaflet map to the coords of the user.But, When compiling the code I get the error

TypeError: Cannot read property 'lat' of null

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
import Constants from "expo-constants";
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";
import { render } from 'react-dom';

import 'leaflet/dist/leaflet.css';



export default class App extends React.Component {
  constructor(){
    super();
    this.state = {
      ready: false,
      where: {lat:null, lng:null},
      error: null
    }
  }

  componentDidMount(){
    let geoOptions = {
      enableHighAccuracy: true,
      timeOut: 20000,
      maximumAge: 60 * 60 * 24
    };
    this.setState({ready:false, error: null });
    navigator.geolocation.getCurrentPosition(this.geoSuccess, this.geoFailure, geoOptions);

  }
  geoSuccess = (position) => {
    console.log(position.coords.latitude);

    this.setState({
      ready:true,
      where: {lat: position.coords.latitude, lng:position.coords.longitude}
    })
  }
  geoFailure = (err) => {
    this.setState({error: err.message});
  }
  
  render() {
    return (
      <MapContainer 
      style={{ height: '100%', width: '100%' }}
      center={[this.state.where.lat, this.state.where.lng]} 
      zoom="30" 
      scrollWheelZoom={true}
      >
        <TileLayer
          attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
    
      </MapContainer>
    );
  }

}
like image 549
kboy Avatar asked Jan 20 '26 16:01

kboy


1 Answers

the <App> component will mount first and then after that componentDidMount() will be called as its name says. The reason you are getting this error is that when <App> will be mounted for the first time the this.state.where will be null.

To avoid this error you can do the following trick:

import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
import Constants from "expo-constants";
import * as Location from "expo-location";
import * as Permissions from "expo-permissions";
import { render } from 'react-dom';

import 'leaflet/dist/leaflet.css';



export default class App extends React.Component {
    constructor() {
        super();
        this.state = {
            ready: false,
            where: { lat: null, lng: null },
            error: null
        }
    }

    componentDidMount() {
        let geoOptions = {
            enableHighAccuracy: true,
            timeOut: 20000,
            maximumAge: 60 * 60 * 24
        };
        this.setState({ ready: false, error: null });
        navigator.geolocation.getCurrentPosition(this.geoSuccess, this.geoFailure, geoOptions);

    }
    geoSuccess = (position) => {
        console.log(position.coords.latitude);

        this.setState({
            ready: true,
            where: { lat: position.coords.latitude, lng: position.coords.longitude }
        })
    }
    geoFailure = (err) => {
        this.setState({ error: err.message });
    }

    render() {
        return (
            <>
                {( this.state.where.lng != null && this.state.where.lat != null) &&
                    <MapContainer
                        style={{ height: '100%', width: '100%' }}
                        center={[ this.state.where?.lat , this.state.where?.lng]}
                        zoom="30"
                        scrollWheelZoom={true}
                    >
                        <TileLayer
                            attribution='&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
                            url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                        />

                    </MapContainer>
                }
            </>
        );
    }

}

In the above code the MapContainer will not render until you will get this.state.where in the state.

UPDATE

Please look at the previous code as well I updated the checks to render the map. You can also check the lng lat by console.log() and if you are not getting them then you can use another package called @react-native-community/geolocation which was working for me;

import 'react-native-gesture-handler';
import React, { Component } from 'react';
import {
    SafeAreaView, StyleSheet, ScrollView, View, StatusBar, Dimensions, Image, TouchableOpacity, TextInput, ToastAndroid, ActivityIndicator,
    LogBox, Keyboard, Modal, TouchableHighlight, PermissionsAndroid, ImageBackground, FlatList, AppState, Linking
} from 'react-native';
import Geolocation from '@react-native-community/geolocation'

export class SignUpScreen extends Component {
    constructor() {
        super()
        this.state = {

            longitude: '',
            latitude: '',
            locationAccuracy: '',

        }
    }
    componentDidMount() {
        Geolocation.getCurrentPosition((info) => {
            this.setState({
                longitude: info.coords.longitude,
                latitude: info.coords.latitude,
                locationAccuracy: info.coords.accuracy,
            })
        })
    }
    render() {
        console.log(this.state)
        return (
            <View>
                {this.state.longitude != '' && this.state.latitude != '' &&
                    <>
                        {/* YOUR MAP */}
                    </>
                }
            </View>
        )
    }
}
export default class App extends Component {
    render() {
        return (
            <SignUpScreen />
        );
    }
}
like image 64
Zeeshan Ahmad Khalil Avatar answered Jan 22 '26 05:01

Zeeshan Ahmad Khalil



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!