javascriptreactjsreact-nativeexporeact-location

Difference between getCurrentPositionAsync and watchPositionAsync and why doesn't anything show up


I'm trying to get the position of the user and have it constantly updating and showing on the screen. I simply can't figure out why this isn't working :(

Here's my code:

import { Alert, Linking, Text, View } from "react-native";
import React, { useEffect, useState } from "react";

import * as Location from "expo-location";

export default function DateFinder() {
  const [hasForegroundPermissions, setHasForegroundPermissions] =
    useState(null);
  const [userLocation, setUserLocation] = useState(null);
  const [textPosition, setTextPosition] = useState("");

  useEffect(() => {
    const AccessLocation = async () => {
      function appSettings() {
        console.warn("Open settigs pressed");
        if (Platform.OS === "ios") {
          Linking.openURL("app-settings:");
        } else RNAndroidOpenSettings.appDetailsSettings();
      }

      const appSettingsALert = () => {
        Alert.alert(
          "Allow Wassupp to Use your Location",
          "Open your app settings to allow Wassupp to access your current position. Without it, you won't be able to use the love compass",
          [
            {
              text: "Cancel",
              onPress: () => console.warn("Cancel pressed"),
            },
            { text: "Open settings", onPress: appSettings },
          ]
        );
      };

      const foregroundPermissions =
        await Location.requestForegroundPermissionsAsync();
      if (
        foregroundPermissions.canAskAgain == false ||
        foregroundPermissions.status == "denied"
      ) {
        appSettingsALert();
      }
      setHasForegroundPermissions(foregroundPermissions.status === "granted");
      if (hasForegroundPermissions == true) {
        console.warn("bob");
        const location = await Location.watchPositionAsync(
          { enableHighAccuracy: true, accuracy: Location.Accuracy.Highest },
          (location) => {
            setUserLocation(location);
            setTextPosition(JSON.stringify(location));
          }
        );

        console.warn("bob");
      }
    };

    AccessLocation().catch(console.error);
  }, []);

  return (
    <View>
      <View>
        <Text>{textPosition}</Text>
      </View>
    </View>
  );

  const styles = StyleSheet.create({
    background: {
      backgroundColor: COLORS.background_Pale,
      flex: 1,
      // justifyContent: "flex-start",
      //alignItems: "center",
    },
    image: {
      flex: 1,
      // height: null,
      // width: null,
      //alignItems: "center",
    },
    scrollView: {
      backgroundColor: COLORS.background_Pale,
    },
  });
}

Sadly, it seems that nothing happens but I don't know why. Nothing shows up in the text and the watchPositionAsync doesn't update. Maybe I need to do something for the screen to update since useEffect only runs everytime the screen is updated but i can't seem to figure out what I should do.


Solution

  • Your state hasForegroundPermissions needs some time to update, so your if(hasForegroundPermissions == true) condition executes before the state update with previous value which in not true. So it won't execute the code inside the if condition. So change your code like below to get that condition to work

    ...
          if (foregroundPermissions.status === "granted") {
            setHasForegroundPermissions(true);
            console.warn("bob");
            const location = await Location.watchPositionAsync(
              { enableHighAccuracy: true, accuracy: Location.Accuracy.Highest },
              (location) => {
                setUserLocation(location);
                setTextPosition(JSON.stringify(location));
              }
            );
            console.warn("location",location);
          }
          else setHasForegroundPermissions(false);
    ...