Search code examples
javascriptangularjsangularjs-scopeangular-promise

Using $q.all sometimes causes selects to not read the model correctly


I noticed that one of my select dropdowns would occasionally not have the correct item selected from the Angular model. I traced it down to be what appears an issue with promises not fulfilling before Angular loads the form. After trying a large amount of different methods, I finally decided to do this non-sense to make it work:

$q.all([
    $scope.categories.$promise,
    $scope.durations.$promise,
    $scope.job.$promise,
    $scope.jobStatuses.$promise,
    $scope.recruiters.$promise,
    $scope.states.$promise
]).then(function () {
    window.setTimeout(function() {
        $scope.editJob = {
            acceptsVisas: $scope.job.acceptsVisas,
            categoryId: $scope.job.categoryID,
            city: $scope.job.city,
            contact: $scope.job.contactID,
            description: $scope.job.details,
            duration: $scope.job.durationID,
            internalId: $scope.job.internalReqID,
            postal: $scope.job.postal,
            recruiter: $scope.job.recruiterID,
            state: $scope.job.stateID,
            status: $scope.job.jobStatusID,
            title: $scope.job.title
        }
    }, 10);
});

Without the setTimeout, the select will occasionally not the wrong recruiter selected. I've debugged it down to something inside Angular/JS. Examining the model shows that the right fields are set before hand, and it's not reliably reproducible, which leads me to the assumption that Angular is loading the form before the promise is finished, and then not selecting the right recruiter when it loads the recruiter data. Nothing is being set out of context, this is pretty much all the code aside from the queries being ran on the resources. I also updated the windows.setTimeout to use $timeout, but the main point of needing to do it in the first place remains.


Solution

  • A year later, and I've found no answer. For all the searching I've done since then, it seems like the simple answer is that it's a flaw in Angular, and there really isn't much to do about it. The timeout solution works, it just shouldn't be needed. Unfortunately, that's the side-effect of third-party software.