ObservableArray not updating
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-debug.js"></script>
<div id="ko">
<ul>
<!-- ko foreach: locations -->
<li>
<strong>
<span data-bind="text: $data.title">first</span>
<span data-bind="text: $data.distance">second</span>
</strong>
<span data-bind="attr: { title: lat + ',' + lng">lat/lng</span>
</li>
<!-- /ko -->
</ul>
</div>
<pre data-bind="text: ko.toJSON($root, 0, 2, true)"></pre>
<div>
<button id="getDist">get distance from:</button>
<input type="text" id="lat" value="0" class="latlng" />
<input type="text" id="lng" value="0" class="latlng" />
<button id="getDevicePos">get current device position</button>
</div>
<div>
CSS
.latlng { width: 30px; }
JavaScript
const locationsMaster = [
{key: 111, title: "Location 111", distance: 0},
{key: 222, title: "Location 222", distance: 0},
{key: 333, title: "Location 333", distance: 0},
];
locationsMaster.forEach(item =>
['lat','lng'].forEach(k =>
item[k] = Math.random().toFixed(8) * 100
)
);
const service = {};
service.loadAllLocations = () => JSON.parse(JSON.stringify(locationsMaster));
service.getDistanceFrom = pos => {
list = [];
locationsMaster.forEach(item => {
distKm = getDistanceKm(pos.lat, pos.lng, item.lat, item.lng);
distObj = {key: item.key, distance: distKm };
list.push(distObj);
});
return JSON.parse(JSON.stringify(list));
};
function ViewModel() {
this.locations = ko.observableArray();
}
var vm = new ViewModel();
ko.applyBindings(vm);
allLocations = service.loadAllLocations(); //will return locations with distance:0
allLocationsMap = [];
allLocations.forEach(item => allLocationsMap[item.key] = item);
vm.locations(allLocations);
$("#getDist").click(function() {
//var distances = service.getDistanceFrom({address:$("#address").val()});
const pos = {};
pos.lat = parseFloat($("#lat").val());
pos.lng = parseFloat($("#lng").val());
var distances = service.getDistanceFrom(pos);
vm.locations.removeAll();
distances.forEach(function(item) {
const clone = Object.assign({},allLocations[item.key]); //clone the orig location
clone.distance = item.distance;
vm.locations.push(clone);
});
});
$("#getDevicePos").click(function() {
navigator.geolocation.getCurrentPosition(function(pos) {
$("#lat").val(pos.coords.latitude);
$("#lng").val(pos.coords.longitude);
}, function(err) { console.log(err); alert(err.message); });
});
//distance calc from https://stackoverflow.com/a/27943/323456
function getDistanceKm(lat1,lon1,lat2,lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
...