Search code examples
react-nativegeolocation

Cannot return position in from navigation.geolocation.getCurrentPosition() in react-native


I am trying to get the geolocation after an image has been taken in react-native. A user captures an image and the image along with the geolocation is stored in an object and sent via a http request to the server.

The function to save get the geolocation works fine bur I am unable to return the geolocation to be stored in the object for http transfer. I get an undefined.

        console.log('getCoordinates run')
        await navigator.geolocation.getCurrentPosition(
            position => {
                let coordinates = `${position.coords.longitude}, 
                      ${position.coords.latitude}`

                return coordinates
            },
            error => Alert.alert(error.message),
            { enableHighAccuracy: false, timeout: 20000, maximumAge: 1000 }
        )

    }


captureImage = async () => {
        if (this.camera) {
            const options = { quality: 0.5, base64: true };
            const data = await this.camera.takePictureAsync(options);
            console.log(data);



            let postData = {
                user: 1,
                coordinates: this.getCoordinates(),
                image: `data:image/jpeg;base64${data.base64}`,
            }
            console.log(postData)

             axios.post('https://localhost:5000/api/posts', postData)
                 .then(post => res.json(post))
                 .catch(err => console.log(err))

        }
    }

Expected results is that when the captureImage function runs the getCoordinates function withing the postData object returns the current geolocation before that data is transferred to the server.


Solution

  • How geolocation.getCurrentPosition function works here is that it sets a callback to send data once it acquire user's location. It takes time to acquire and send relevant data. That's why we use callbacks or promises. But in your code, you just call the function and without waiting for its response, just do the API call.

    I assume you have used Async function to do this. But if I were you, I'd try to use Promises here to resolve this issue. Simple example would be,

    captureImage = async () => {
        if (this.camera) {
            // ... do your camera tasks
        }
    
        this.sendImageData(data); // data is what you got from camera.
    }
    
    getGeoInfo = () => {
       return new Promise((resolve, reject) => {
           navigator.geolocation.getCurrentPosition(
            position => {
                let coordinates = `${position.coords.longitude}, 
                      ${position.coords.latitude}`
    
                resolve(coordinates);
            },
            error => reject(error),
            { enableHighAccuracy: false, timeout: 20000, maximumAge: 1000 }
          )
       })
    }
    
    sendImageData = (cameraData) => {
       let coordinates = '';
       getGeoInfo.then(crdnts => coordinates = crdnts );
    
       // now coordinates have all relevant data you wished.
       const data = { //... make the object as you want }
       // do the API call using axios as you've already done.
    }