1

How to create a AngularJS promise from a callback-based API

Why are Callbacks from Promise .then Methods an Anti-Pattern

I have an Angularjs 1.5 modal component as below. The modal opens and on render event it calls a function outside of the angular app with a callback function contained in this component. This outside function initiates a install process which then periodically calls another function reportbackStatus which calls the callback and returns the message.

The issue I am having is the binding is not being updated in the template on each callback function call. The console.log is executed and i can see the message in the console. The binding is initially updated with 'starting process' so binding is correct

<span ng-bind="$ctrl.messages[$ctrl.messages.length - 1]"></span>

I tried wrapping code in scope.apply function as below but i get Error: $rootScope:inprog Action Already In Progress issue. Only when all is completed is the last message shown from the final callback call.

is this the correct way to handle multiple callbacks and updating bindings

  angular.module('components')
  .component('testModal', {
    bindings:{
      modalInstance: '<',
      resolve: '=',
      dismiss: '&',
      close: '&'
    },
    controller: TestController,
    templateUrl: 'scripts/components/TestModal.html'
});

TestController.$inject = ['$scope'];
function TestController($scope) {
  var ctrl = this;

  ctrl.$onInit = function(){
    ctrl.messages = [];
    ctrl.messages.push('starting process');
  };

  ctrl.modalInstance.rendered.then(function(){
    CallVanillaJSFunction(callback); 
  });

  function callback(message){
    ctrl.messages.push(message);
    console.log(ctrl.messages[ctrl.messages.length - 1]);
    CheckScopeBeforeApply();
  }

  function CheckScopeBeforeApply() {
    if(!$scope.$$phase) {
      $scope.$apply();
      console.log('scope applied');
    }
  };

}

Vanilla Function

var globalCallback;

function CallVanillaJSFunction(callback){
    globalCallback = callback;
    initiateprocess();  
}

function reportbackStatus(message){
   globalCallback(message);
}

The global callback function can be called multiple times and the angular application does not know how many times it will be called.

georgeawg
  • 48,608
  • 13
  • 72
  • 95

0 Answers0