Reputation: 4839
I found a SO question that showed me how to use an Angular UI - Bootstrap typeahead with $http object. It worked fine (see first plunk) until I changed the Angular version to 1.2RC2 which it is now failing on. I do not know the Angular code well enough to figure out why. What changed between 1.05 and 1.2 to break this code
This plunk works: http://plnkr.co/edit/eGG9Kj?p=preview
This plunk doesn't work: http://plnkr.co/edit/HdVBpp?p=preview
The relevant code
HTML
<html ng-app="plunker">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.js"></script>
<script src="http://angular-ui.github.com/bootstrap/ui-bootstrap-tpls-0.2.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
</head>
<body>
<alert type="'info'" >Typeahead from <a href="http://angular-ui.github.com/bootstrap/">http://angular-ui.github.com/bootstrap/</a>"</alert>
<div class='container-fluid' ng-controller="TypeaheadCtrl">
<pre>Model: {{result | json}}</pre>
<input type="text" ng-model="result" typeahead="suggestion for suggestion in cities($viewValue)">
</div>
</body>
</html>
Javascript
angular.module('plunker', ['ui.bootstrap']);
function TypeaheadCtrl($scope, $http, limitToFilter) {
//http://www.geobytes.com/free-ajax-cities-jsonp-api.htm
$scope.cities = function(cityName) {
return $http.jsonp("http://gd.geobytes.com/AutoCompleteCity?callback=JSON_CALLBACK &filter=US&q="+cityName).then(function(response){
return limitToFilter(response.data, 15);
});
};
}
It fails inside the Angular UI Code at line 1564 where it is unable to find the matches.length
beacause matches is undefined.
Upvotes: 0
Views: 970
Reputation: 1143
https://github.com/angular/angular.js/issues/4158
https://github.com/angular-ui/bootstrap/issues/949
It is directly related to this change in 1.2.0-rc2. Previously when a function call was evaluated using scope.$eval and returned a promise, it would return the raw promise object. The change implemented made it so the promise return values are being automatically resolved, causing the value to be undefined. Since the typeahead directive doesn't expect this behavior it crashes.
You can temporarily fix the issue by having your function hack the promise a bit:
promise.$$v = promise;
$$v is the value that angular will internally return when automatically resolving promises, and it will assign the result of the promise to that value as well.
I would recommend sticking with rc1 or waiting for rc3, as this issue and functionality is likely to be changed.
Just some extra info - I believe that before RC2, promise objects evaluated on the scope would be automatically resolved, but function calls which returned promises were not. The change was made to maintain consistent functionality in the handling of promises.
Upvotes: 4