Home > database >  why does my recussion stop after 10 or 15 times?
why does my recussion stop after 10 or 15 times?

Time:12-08

I made a recursive loop, at the moment without a stopping criterium bus I don't think that should matter. I don't create any variable within the loop, and I just dont understand why it stops:

 async function locagetter() {
  return await Location.getCurrentPositionAsync({enableHighAccuracy: true});
}

async function calcdist(val) {
  console.log("hoi");
    val = await locagetter();
    await SetDistance(getPreciseDistance(
      {latitude: 51.493280, longitude: 4.294605 },
      {latitude: val.coords.latitude, longitude: val.coords.longitude}));
      calcdist(val);
}

I tried alot also promises, but i think it should work, I just need a continuous location refresh.

CodePudding user response:

If you need a continous refresh then why not just use an interval? As of now your recursion doesnt have a break condition so it might still run when the component unmounts (Im not sure about this so dont quote me) where as with an interval you can start stop it on unmounts:


const intervalId = useRef()
const startCoordinate = {latitude: 51.493280, longitude: 4.294605 }
const calcLocationDist = async (coordinate=startCoordinate)=>{
  let currentCoordinate = await Location.getCurrentPositionAsync({
    enableHighAccuracy: true
  });
  SetDistance(getPreciseDistance(coordinate,currentCoordinate)
}
useEffect(()=>{
  intervalId.current = setInterval(()=>{
    calcLocationDist();
  },1000)
  // for component unmounts
  return ()=>{
    clearInterval(intervalId.current)
  }
},[])

You could take things a step further and create a useCurrentLocation hook. It would allow you do more without cluttering the component that uses it:

const defaultConfig = {
  // interval updates in seconds
  updateInterval=10,
}
export default function useCurrentLocation({onUpdate, one rror,updateInterval}=defaultConfig){
  // track errors
  const [error, setError] = useState(null);
  const [value, setValue] = useState({});
  // toggle the interval on and off
  const [shouldUpdate, setShouldUpdate] = useState(true);
  const intervalId = useRef()
  const update = async ()=>{
    try{
      let loc = await Location.getCurrentPositionAsync({
        enableHighAccuracy: true
      });
      setValue(loc);
      onUpdate?.(loc);
    } catch(err){
      setError(err)
      one rror?.(setShouldUpdate,error)
    }
  }
  useEffect(()=>{
    if(shouldUpdate){
      intervalId.current = setInterval(()=>{
        update()
      },updateInterval*1000)
    }
    else 
      clearInterval(intervalId.current)
    }
    return ()=>{
      clearInterval(intervalId.current)
    }
  },[shouldUpdate])
  return {
    value,
    error,
    shouldUpdate:setShouldUpdate
  }   
}

Then in the component that uses the location:

const startCoordinate = {latitude: 51.493280, longitude: 4.294605 };
const [permissionStatus, requestPermission] = Location.useForegroundPermissions();

const location = useCurrentLocation({
  updateInterval:5,
  onUpdate:newLocation=>{
   SetDistance(getPreciseDist(startCoordinate,newLocation))
  },
  one rror:(error,shouldUpdate)=>{
    console.log(error)
    // stop interval
    shouldUpdate(false)
  }
});
// location.value is current location
console.log(location.value)
// location.error is last error 
console.log(location.error)
// location.shouldUpdate is a function that will accept a boolean
// that will turn the interval on or off
useEffect(()=>{
  // if permission is granted turn interval on
  if(permissionStatus?.granted)
    location.shouldUpdate(true)
  else{
   // turn interval off
   location.shouldUpdate(false)
   // if permission can be request again attempt to do so
   if(permissionStatus.canAskAgain)
     requestPermission()
  }
},[permissionStatus])
  • Related