5

In my app I have some data that I fetch from a service that I then proceed to use in my code to preload a form. However, sometimes the data isn't loaded until after the rest of the code is run, so the form comes up blank. Other times, it's fine and everything loads. I want to make it such that it always loads the form with all fields populated.

The problem is that I have multiple service calls, so how do I make sure that all services have finished loading? Here is my code:

In Reference Data Service (the rest of the GETs pretty much use the same kind of code):

        factory.getAllOffices= function(){
          var deferred = $q.defer();
          $http.get(APP_CONFIG.refURL+"/reference/getAllOffices")
            .success(function(response){
                deferred.resolve(response);
            })
            .error(function(msg, code, headers, config){
                console.log(msg);
                deferred.reject(msg);
            });
        return deferred.promise;
    };

In the controller:

    referenceDataService.getAllOffices().then(function(data){
        $scope.allOffices= data;
    });

    referenceDataService.getAllTypes().then(function(data){
        $scope.allTypes= data;
    });

    referenceDataService.getAllTeams().then(function(data){
        $scope.teamOptions.data = data;
    });

    //Checking to see if form exists.
    $scope.formID= '';

    if(!angular.isUndefinedOrNull($routeParams.id)){
        $scope.formID= $routeParams.id.substring(1);
    }

    if (!($scope.formID== '')){
        addFormService.getForm($scope.formID).then(function(data) {

            var officeIndex=angular.findIndexOf($scope.allOffices, data.officeID);
            var typeIndex=angular.findIndexOf($scope.allTypes, data.typeID);

            $scope.form.name= data.name;
            $scope.report.office= $scope.allOffices[officeIndex];
            $scope.report.type= $scope.allTypes[typeIndex];
            $scope.teamOptions.data = data.teamList;
            $scope.report.teams= data.teams;

            angular.forEach($scope.report.teams, function(id) {
                $scope.teamOptions.grid.rows.map(function (row) {
                    if (row.entity.id == id) {
                        row.setSelected(true);
                    }
                });
            });
        });
    }

Sometimes Offices, Types, and Teams aren't returned before the formID code runs.

2
  • "Sometimes" you mean every time? Commented Nov 2, 2015 at 20:45
  • By the way instead of using $q.defer at all you can just return the promise that is returned from the $http call. Commented Nov 2, 2015 at 20:47

1 Answer 1

6

You can use q.all(), as it accepts an array of promises that will only be resolved when all of the promises have been resolved.

$q.all([
      referenceDataService.getAllTypes(),
      referenceDataService.getAllTeams()
    ]).then(function(data){
      $scope.allTypes = data[0];
      $scope.teamOptions.data = data[1];
 });

You can also choose when to show/hide certain elements using ng-hide/ng-show. You can initialize the page with $scope.showProperty = false; and once your service calls have resolved, switch it: $scope.showProperty = true;.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.