KSJaay
KSJaay

Reputation: 59

Unable to remove Expo Location.watchPositionAsync()

I wanted to be able to track user locations for some features in my application, but I want users to be able to turn off location if they want. I've been using expo-location to find the users location, request permission and varies other things. But when I use watchPositionAsync, I can't remove it when the user turns it off the feature. I read the docs and it said that I could use remove() but I get the following error when I try to do that:

Unhandled promise rejection: TypeError: client.location.remove is not a function. (In 'client.location.remove()', 'client.location.remove' is undefined)

For reference client is just a global object which stores some settings for the user (It's so I don't have to keep fetching it over and over again).

client.js

let client = {
   user: {},
   location: null
};

tracking.js

import * as Location from 'expo-location';

export async function startTracking(client){
    console.log('Starting tracking')
    if(!client.location){
        client.location = Location.watchPositionAsync({
            accuracy: Location.Accuracy.Highest,
            distanceInterval: 1,
            timeInterval: 5000,
        }, (loc) => {
            console.log(loc)
        });
    }
}


export async function stopTracking(client){
    console.log('Remove tracking')
    await client.location.remove();
}

More information:

Upvotes: 3

Views: 3224

Answers (2)

veelon
veelon

Reputation: 66

A straightforward and more generic implementation as a hook:

import * as Location from 'expo-location';
import { useEffect, useState } from 'react';

export const useUserLocation = () => {
  const [userLocation, setUserLocation] = useState<Location.LocationObjectCoords | null>(null);

  useEffect(() => {
    let subscription: Location.LocationSubscription | null = null;

    (async () => {
      const { status } = await Location.requestForegroundPermissionsAsync();
      if (status === 'granted') {
        subscription = await Location.watchPositionAsync(
          { accuracy: Location.Accuracy.BestForNavigation },
          ({ coords }) => setUserLocation(coords),
        );
      } else {
        console.log('Location permissions not granted');
      }
    })();

    return () => {
      subscription?.remove();
    };
  }, []);

  return userLocation;
};

Upvotes: 0

docmurloc
docmurloc

Reputation: 1239

You are not waiting the returned object by the function watchPositionAsync.

Returns a promise resolving to a subscription object, which has one field

I take this source.

Try this code.

import * as Location from 'expo-location';

export async function startTracking(client){
    console.log('Starting tracking')
    if(!client.location){
        client.location = await Location.watchPositionAsync({
            accuracy: Location.Accuracy.Highest,
            distanceInterval: 1,
            timeInterval: 5000,
        }, (loc) => {
            console.log(loc)
        });
    }
}


export async function stopTracking(client){
    console.log('Remove tracking')
    await client.location.remove();
}

Upvotes: 5

Related Questions