4

Before AngularJS 1.5, in directives or views, the way to make sure a change would be picked up by angular (using $digest cycle) when the change was issued from a third party async callback was to run your code in a $scope.$apply() call.

With components, as far as I understood, the idea is to get rid of $scope and just bind the template to the component's controller. I'm trying to transition to writing components instead of views, without relying on $scope. Let's say I have the following code:

function CompController(TPApi) {
    let self = this;
    this.endCallback = false;
    TPApi.call(data, () => this.endCallback = true );
}

angular.module('app',  []).component('myComp', {
    controller: CompController,
    template: '<div><span ng-show="$ctrl.endCallback">Callback Called</span></div>'
})

The problem here is that ng-show is double binded to the controller, but without using $scope.$apply() for the callback, the change won't be picked up by the ng-show since the $digest cycle won't be triggered. This is very much an annoyance because I would have to then inject $scope in the controller and call $apply, but that defeats the purpose of relying on $scope in the first place.

I guess a way would be to encapsulate the TPApi with the $q service thus making sure the $digest cycle is called when the callback is issued. But what if at some point I want to transition to using the new native Promise API instead of $q?

Is there a smart way to do this without triggering $digest or is angular 1 just inherently flawed because of $scope and $digest?

  • Can you reproduce this behaviour in a fiddle? Your example behaves normally, the model is updated after the api call. – gyc Jul 07 '16 at 22:42
  • Here you go: https://jsfiddle.net/xgcphw0m/4/ Used geolocation. If you've used an angular service like $q or $http it will work but that's because they wrap the callback with $apply. That's what I want to avoid. – Lucian Onea Jul 08 '16 at 09:00
  • Unfortunately I don't know much about es6. – gyc Jul 08 '16 at 09:35
  • Then learn it, its simple! – ey dee ey em Sep 20 '16 at 22:50

1 Answers1

0

Since you are calling a third party API, You will have to let angular to update and recognize the new data arrived. If you don't want to use $scope, you can wrap your code with $timeout (Which triggers the digest cycle for you)

function CompController(TPApi) {
    let self = this;
    this.endCallback = false;
    TPApi.call(data, () => $timeout(() => this.endCallback = true, 0));
}
Dima Grossman
  • 2,800
  • 2
  • 21
  • 26