0

I'm trying to fire some code after and when a user has made a selection from select menus. Therefor I was trying to use promises and the $scope.$watch function. I'm resolving the promise in that watch function but the then function of the promise doesn't get fired. $scope.$apply() doesn't seem to work in this context. How can I get this then function to fire?

Here's the code:

var nameSpace = angular.module("test", []);
nameSpace.controller("DataRetriever", ['$scope','$http', '$q', function($scope, $http, $q)
{
    $scope.options = ["1","2","3"];
  $scope.displayText = false;
    console.log("options set");
    var deferred = $q.defer();
    $scope.selectedOption = "";
    $scope.$watch("selectedOption", function (newValue, oldValue) {
        if (newValue != "") {
            deferred.resolve(newValue);
            console.log("Resolve called! New value: ", newValue);
        } else {
            deferred.reject("Invalid option!");
        }
    });
    deferred.promise.then(function(data){
        $scope.displayText = true;
        console.log("Then success callback function executed!");
    });
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test" ng-controller="DataRetriever as dr">
<select ng-model="selectedOption"><option ng-repeat="option in options">{{option}}</option>
</select>
  <div ng-show="displayText">Then success callback function executed!</div>
</div>
Ray Za
  • 13
  • 1
  • You could think that $watch() call as giving you a promise, that it would be called when user change a value exposed on scope. Wouldn't it work for you? – André Werlang Jan 19 '15 at 02:10
  • perharps you have something in mind, but I wanted to ask anyway. – André Werlang Jan 19 '15 at 02:10
  • @Werlang I guess probably OP is trying to achieve change event handler. – PSL Jan 19 '15 at 02:19
  • @PSL well, I'm intrigued by this one. hope he can provide a reason. – André Werlang Jan 19 '15 at 02:37
  • Actually I try to have have several select elements. Only once **every** select element has a selected option, a HTTP GET request with the values of these select elements should be made. And since I can check through $q.all(promises) whether all promises have been resolved and only then call a function, I thought I should use them. Now since I need the request to fire again as soon as a value of a select element has changed I tried to use $watch to achieve this. – Ray Za Jan 20 '15 at 10:54

2 Answers2

1

Promises will only be resolved once so the first time will succeed and do what you want but anytime after that it won't resolve it again. [Ref] so what you are trying to accomplish is not possible with promises.

Community
  • 1
  • 1
dbarnes
  • 1,803
  • 3
  • 17
  • 31
0

Why you code is not working is because the first resolution is a reject, you can verify by adding console.log in the else condition. Once rejected the promise cannot be changed, and hence the behaviour.

@PSL is right use standard ng-change

Chandermani
  • 42,589
  • 12
  • 85
  • 88