I’m not a coder, so go easy on me please.
I am trying to arrange a 100+ store location dataset to sort into a repeater according to the nearest store to a user based on their geolocation. I originally looked at ways to set it up as a wixdata query then feed the results into the repeater, which worked fine when the page loaded, but fell apart as soon as filters or other sorts were applied to the dataset.
So what I am looking to do is when the page first loads calculate and store the distance for each venue in the Distance field of the dataset (not the collection). Then once these calculated distances are in the dataset I can apply data filters and sort the resulting filtered items by nearest location into the repeater, or use the indexed Distance for other calculations on the page.
The idea was on page load to loop through each item in the dataset from 1 to [datasetlength], with each pass using setCurrentItemIndex() and getCurrentItem() to get a single “row” of store location data, calculate its distance and then use setFieldValue() to set the store’s Distance before moving on to the next row.
The dataset is connected to the repeater and all the data filter options via the Editor (not coded), while the sort options are coded to run on a button onClick(). Everything is synced & working perfect except the initial function to store each location’s calculated mDistance in the dataset.
The console logs show that the location data is retrieved correctly and the distance calculation function works fine (kudos to the original author), but instead of looping through each item in the dataset from 1 to [datasetlength], it just repeats the last calculated item in the dataset over and over.
#dataset1: has read/write permissions, and is linked to 100-item collection “ShoppingDB” that includes these field keys:
- mListing: text, the name of the venue
- mgps: numeric, the latitude of the venue
- mgps1: numeric, the longitude of the venue
- mDistance: numeric, this field is blank in the collection and can be used to store each item’s calculated distance in #dataset1
Here are the relevant pieces of code:
import wixData from 'wix-data';
import wixWindowFrontend from 'wix-window-frontend';
$w.onReady(function () {
$w("#dataset1").onReady( () => {
//On load, default sort dataset by Nearest
SortbyNearest()
});
});
function SortbyNearest(){
wixWindowFrontend.getCurrentGeolocation()
.then((obj) => {
let lat1 = obj.coords.latitude; //current latitude of the user
let long1 = obj.coords.longitude; //current longitude of the user
let datasetlength = $w("#dataset1").getTotalCount();
console.log("Your coordinates: " + lat1 + " , " + long1);
console.log("dataset length = " + datasetlength.toString())
for (var i = 0; i < datasetlength; i++) {
$w("#dataset1").setCurrentItemIndex(i)
.then( () => {
let venue = $w("#dataset1").getCurrentItem();
let lat2 = venue.mgps; //get venue latitude from dataset
let long2 = venue.mgps1; //get venue longitude from dataset
let distance = dist(lat1, long1, lat2, long2); //calculate distance between user and venue
$w("#dataset1").setFieldValue("mDistance", Number(distance));//Set the current item's distance (but only in the dataset)
console.log(i + " " + venue.mListing + " (" + distance + " km away)")
});
}
})
}
function dist(lat1, lon1, lat2, lon2) {
function rad(x) { return x * Math.PI / 180; }
let R = 6378.137;
let dLat = rad(lat2 - lat1);
let dLong = rad(lon2 - lon1);
let a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(rad(lat1)) * Math.cos(rad(lat2)) * Math.sin(dLong / 2) * Math.sin(dLong / 2);
let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d.toFixed(2); // return distance in km to 2 decimal points
}
//END
Once all the distances are in the dataset, the user can click buttons to change the sort parameter of the repeater and whatever filters are applied. Example:
// click button to sort by Nearest
$w("#button189").onClick(() => {
$w("#dataset1").setSort(
wixData.sort()
.ascending("mDistance")
);
})