Nag tech
Nag tech

Reputation: 45

Angular - waiting for request in other controller to complete

I have two controllers which are loaded parallel, Controller A calls Service A and Controller B calls Service B. Controller B requires data which Controller A is requesting. (Note : Controller A is a common controller so I cannot call service A in Controller B)

What is the best approach for Controller B to process data only after both service calls (from Ctrl A and Ctrl B) are completed?

I saw some of $q examples and I am bit confused implementing it in above situation.

Upvotes: 1

Views: 1026

Answers (1)

Icycool
Icycool

Reputation: 7179

I would handle your case by using a one time $watch in Controller B that make sure the existence of both service variable before proceeding.

angular.module('test', [])
  .controller('ControllerA', ControllerA)
  .controller('ControllerB', ControllerB)
  .factory('ServiceA', ServiceA)
  .factory('ServiceB', ServiceB);

function ControllerA($scope, ServiceA) {
  $scope.a = 'a';
  
  ServiceA.getString().then(function(){
    $scope.a = ServiceA.str;
  });
}

function ControllerB($scope, ServiceA, ServiceB) {
  $scope.b = 'b';
  $scope.ab = 'ab';
  
  ServiceB.getString().then(function(){
    $scope.b = ServiceB.str;
  });
  
 // --- this part is the answer ---
  var watch = $scope.$watchCollection(function(){
    return [ServiceA.str, ServiceB.str];
  }, function(){
    if (!ServiceA.str || !ServiceB.str) return;
    
    $scope.ab = ServiceA.str + ' and ' + ServiceB.str;
    watch(); // unregister watch
  });
  // --- end answer ---
}

function ServiceA($timeout, $q) {
  var service = {
    str: "",
    getString: getString
  }
  
  return service;
  
  function getString() {
    var d = $q.defer();
    
    $timeout(function(){
      service.str = "I'm string A";
      d.resolve();
    }, Math.random() * 3000);
    
    return d.promise;
  }
}

function ServiceB($timeout, $q) {
  var service = {
    str: "",
    getString: getString
  }
  
  return service;
  
  function getString() {
    var d = $q.defer();
    
    $timeout(function(){
      service.str = "I'm string B";
      d.resolve();
    }, Math.random() * 3000);
    
    return d.promise;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>

<div ng-app='test'>
  <div ng-controller="ControllerA">{{a}}</div>
  <div ng-controller="ControllerB">
    {{b}}
    <br>{{ab}}
  </div>
</div>

Upvotes: 1

Related Questions