Ad

Data Binding Does Not Update After Putting New Data In Variable

- 1 answer

Hope somebody can help me I am really new to Angular and all this binding stuff. But the problem what I have is the following. I create a list based of an array of items with ng-repeat. But later in my code I calculate the distance and duration of a direction. This data I also add to my array but it doesn't update the list. It only updates if I press on a orderby button.

Hope somebody can help me with this problem.

this is my app.js code:

var app = angular.module("myapp", ['ui.bootstrap']);
var OpenWifiData = {}; //variable to store openWifiData
var initialLocation;
var geoLocation = new Boolean();
var distance = 999999999999999999999999999999999999;
var closest;
var OpenWifiDataReceivingStarted = false;
app.factory('myService', function ($http) {
    var myService = {
        async: function () {

            var promise = $http.get('http://localhost:3000/api/openData').then(function (response) {


                OpenWifiData = response.data;
                return response.data.data;
            });

            return promise;
        }
    }
    return myService;
});
app.factory("OpenDataService", function () {
    return { opendata: "" };
});



app.controller("MapController", function ($scope, $interval, $http, myService, OpenDataService) {
    if (!OpenWifiDataReceivingStarted) {
        OpenWifiDataReceivingStarted = true;
        OpenWifiData = myService.async().then(function (d) {

            initialize();
        });
    }
    initialize = function () {
        var callbackCounter = 0;
        directionsService = new google.maps.DirectionsService;
        directionsDisplay = new google.maps.DirectionsRenderer;
        map = new google.maps.Map(document.getElementById('map'), {
            zoom: 14
        });

        var icon = {
            url: "../Images/WifiIcon.png",
            scaledSize: new google.maps.Size(50, 50)
        };


        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(function (position) {
                initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                geoLocation = true;
                map.setCenter(initialLocation);
                putMarkers(position.coords.latitude, position.coords.longitude, geoLocation);

            }, function () {
                geoLocation = false;
                handleNoGeolocation(geoLocation);
            });
        }

        else {
            geoLocation = false;
            handleNoGeolocation(geoLocation);
        }

        function handleNoGeolocation(geoLocationSucces) {
            map.setCenter({ lat: 51.219710, lng: 4.409398 });
            putMarkers(51.219710, 4.409398, geoLocationSucces);
        }

        function putMarkers(userLat, userLong, geoLocationSucces) {

            for (var i = 0 ; i < OpenWifiData.data.length; i++) {
                marker = new google.maps.Marker({
                    map: map,
                    position: { lat: parseFloat(OpenWifiData.data[i].point_lat), lng: parseFloat(OpenWifiData.data[i].point_lng) },
                    title: OpenWifiData.data[i].locatie,
                    icon: icon

                });

                newDistance = Math.abs(userLat - parseFloat(OpenWifiData.data[i].point_lat)) + Math.abs(userLong - parseFloat(OpenWifiData.data[i].point_lng));
                if (distance > newDistance) {
                    distance = newDistance;
                    closest = OpenWifiData.data[i].objectid - 1;

                }
                if (geoLocationSucces) {
                    var service = new google.maps.DistanceMatrixService();
                    service.getDistanceMatrix(
                      {
                          origins: [initialLocation],
                          destinations: [{ lat: parseFloat(OpenWifiData.data[i].point_lat), lng: parseFloat(OpenWifiData.data[i].point_lng) }],
                          travelMode: google.maps.TravelMode.WALKING
                      }, callback);

                    function callback(response, status) {



                        OpenWifiData.data[callbackCounter].distance = response.rows[0].elements[0].distance.text;
                        OpenWifiData.data[callbackCounter].duration = response.rows[0].elements[0].duration.text;
                        callbackCounter++;


                    }
                }
            }

            OpenDataService.opendata = OpenWifiData;



            if (geoLocationSucces) {
                marker = new google.maps.Marker({
                    map: map,
                    position: initialLocation,
                    title: "User"
                });
                directionsDisplay.setMap(map);
                $scope.calculateAndDisplayRoute(closest);

            }
        }



        onChangeHandler = function () {
            calculateAndDisplayRoute(directionsService, directionsDisplay);
        };

    }


    $scope.calculateAndDisplayRoute = function (id) {
            directionsService.route({
            origin: initialLocation,
            destination: { lat: parseFloat(OpenWifiData.data[id].point_lat), lng: parseFloat(OpenWifiData.data[id].point_lng) },
            travelMode: google.maps.TravelMode.WALKING
        }, function (response, status) {
            if (status === google.maps.DirectionsStatus.OK) {
                directionsDisplay.setDirections(response);
            } else {
                window.alert('Directions request failed due to ' + status);
            }
        });
    }

});

app.controller("ListController", function ($scope, $interval, $http, myService, OpenDataService) {
    myService.async().then(function (d) {

        OpenDataService.opendata = d;

        $scope.openData = OpenDataService.opendata;
        $scope.order = "";



    });

    $scope.orderOptions = ["gemeente", "locatie"];


    $scope.change = function (value) {
        console.log("change");

        $scope.order = value;
        console.log(value);
    }
    $scope.test = OpenWifiData;


});

And here is the html code I use:

<div id="WifiSpots" ng-controller="ListController" class="col-sm-12 col-md-4 col-md-offset-2">
                <div  ng-repeat="item in openData | filter:searchText | orderBy: order">
                    <ul class="list-group">
                        <li class="list-group-item">
                            <div class="row wifiSpots" >
                                <div class="col-md-2">{{item.locatie}}</div>
                                <div class="col-md-2">{{item.gemeente}}</div>
                                <div clas="col-md-1">{{item.distance}}</div>
                                <div clas="col-md-1">{{item.duration}}</div>
                                <button ng-controller="MapController" ng-click="calculateAndDisplayRoute(item.objectid)" class="btn ">Selecteer</button>
                            </div>
                        </li>
                    </ul>
                </div>
            </div>
Ad

Answer

navigator.geolocation.getCurrentPosition is not an Angular function and when its callbacks execute the digest cycle will not be triggered. This means there will be no dirty checking and the UI will not be updated.

You will need to trigger it manually, for example with $apply:

navigator.geolocation.getCurrentPosition(function(position) {

  $scope.$apply(function() {
    initialLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
    geoLocation = true;
    map.setCenter(initialLocation);
    putMarkers(position.coords.latitude, position.coords.longitude, geoLocation);
  });

}, function() {

  $scope.$apply(function() {
    geoLocation = false;
    handleNoGeolocation(geoLocation);
  });

});
Ad
source: stackoverflow.com
Ad