Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update Ionic view from async callback

I am using the phonegap-estimotebeacons plugin in my Ionic app to range some beacons. When it gets updated beacon info, I want it to update the view, but my list doesn't get updated until I switch to a different tab and then switch back.

Here's my view that lists all the found beacons:

<ion-view view-title="Beacons">
  <ion-content>
    <ion-list>
      <ion-item ng-repeat="beacon in beacons" type="item-text-wrap">
        <span>{{beacon.macAddress}}</span>
        <span>{{beacon.distance}}</span>
      </ion-item>
    </ion-list>
  </ion-content>
</ion-view>

Here's the controller that renders the view:

.controller('BeaconsCtrl', function($scope, Beacons) {
  $scope.beacons = [];
  Beacons.range($scope);
})

The Beacons factory then starts to range the beacons and update the scope on every success callback:

.factory('Beacons', function() {
  rangeBeacons = function($scope) {
    var success = function(beaconInfo) {
      $scope.beacons = beaconInfo.beacons;
    };

    var failure = function(errorMessage) {
      alert(errorMessage);
    };

    EstimoteBeacons.startRangingBeaconsInRegion(
      {},
      success,
      failure
    );
  };

  return {
    range: rangeBeacons
  };
})

From other examples I've seen, it looks like my view should react when I update the $scope object, but I have to go to a different tab and then come back in order for my view to be updated. What can I do to get the view to update as soon as the $scope variable is modified?

Update

Modified the controller code to show that I have attempted to initialize $scope.beacons to an empty array, but this makes no difference.

like image 712
Samo Avatar asked Aug 28 '26 20:08

Samo


1 Answers

I found the solution. Because the callback takes place outside of the digest cycle, we need to call $scope.$apply(). Initializing the beacons to an empty array is not necessary.

Updated controller code:

.controller('BeaconsCtrl', function($scope, Beacons) {
  Beacons.range($scope);
})

Updated service code:

.factory('Beacons', function() {
  rangeBeacons = function($scope) {
    var success = function(beaconInfo) {
      $scope.beacons = beaconInfo.beacons;
      $scope.$apply();
    };

    var failure = function(errorMessage) {
      alert(errorMessage);
    };

    EstimoteBeacons.startRangingBeaconsInRegion(
      {},
      success,
      failure
    );
  };

  return {
    range: rangeBeacons
  };
})
like image 196
Samo Avatar answered Aug 30 '26 10:08

Samo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!