0

I am attempting to get the distance between to lat|long coordinates by using the npm geolib. I have a function in which I query firestore and get an array of objects back. I then run that array through a for loop where I call geolib.getPreciseDistance to get the distance for each object of the array.

I am having a hard time getting a sorted array in return from the for loop. In a perfect world the new array would be sorted with the object with the closest distance in index[0].

I've posted as far as I have got below. I appreciate any and all feedback as I am still learning. Thanks!

  function getNearestWalk() {
    let currentLng = userLocation.longitude;
    let currentLat = userLocation.latitude;
    firestore()
      .collection('Walks')
      .where('status', '==', 'started')
      .limit(10)
      .get()
      .then((walks) => {
        const walksArray = [];
        walks.forEach((liveWalks) => {
          walksArray.push(liveWalks.data());
        });
        console.log(walksArray);

        for (var i = 0; i < walksArray.length; i++) {
          geolib.getPreciseDistance(
            { latitude: currentLat, longitude: currentLng },
            {
              latitude: walksArray[i].latitude,
              longitude: walksArray[i].longitude,
            }
          );
        }
      });
  }
3
  • do you want to sort walsArray or after the for loop there is another array or object you want to sort? if after the loop provide us the data you are getting from the loop Commented Jan 20, 2021 at 1:07
  • @Elnatanvazana thank you for the quick response. I'd like the for loop to return a new array sorted by the action performed in the loop. The loop is getting the distance between a constant position and the position of each object in the array. I am trying to get a new array with the object with the shortest distance in the first index position. I hope that makes sense. Thanks again! Commented Jan 20, 2021 at 1:19
  • can you please share one object that you receive from geolib.getPreciseDistance() , please edit your question and add it, you can do console.log(geolib.getPreciseDistance({//put parameters here},{//put parameter here})) Commented Jan 20, 2021 at 12:14

2 Answers 2

1

From what I gathered in your response to @Elnatan, sounds like you want an array of objects representing coordinates sorted by shortest...farthest distance

The most straightforward way (without regard to complexity) is below:

  • Create a helper function distCalc that accepts an object to perform your loop logic that called geolib.getPreciseDistance and returns its value.
  • Then you can set a variable that points to the evaluation of:
    walksArray.sort( (a, b) => distCalc(a) - distCalc(b) )
  • Return your sorted array.

Personally, I would separate concerns in your #getNearestWalk for best practice and create a helper function that fetches your walks so as to implement effective error handling with try {} catch {} since asynchronous calls are not guaranteed.

Let me know if this works for you!

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @DanderMensch! It seems there was a helper function in the code base already so this worked great thanks!
1

In the OP code, walks is a querySnapshot. The first thing to do is extract the doc data. This function does the query and gets the docs' data...

function getStartedWalks() {
  return firestore()
      .collection('Walks')
      .where('status', '==', 'started')
      .limit(10)
      .get()
      .then(querySnapshot => querySnapshot.docs.map(d => d.data()));
}

This function assigns distance from a given point into the doc data...

// to each doc in docs, assign the distance from a given position
function assignDistances(docs, position) {
  return docs.map(doc => {
    const docPosition = { latitude: doc.latitude, longitude: doc.longitude };
    const distance = geolib.getPreciseDistance(position, docPosition);
    return { ...doc, distance }
  })
}

Now getNearestWalk() is easy to write...

function getNearestWalk(position) {
  return getStartedWalks().then(docs => {
    docs = assignDistances(docs, position)
    return docs.sort((a, b) => a.distance - b.distance)
  });
}

Call it like this...

getNearestWalk(userLocation.latitude, userLocation.longitude).then(array => {
  // array will be the doc data, sorted by distance from userLocation
})

1 Comment

thanks! I tried your solution as well and it worked as expected!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.