I am using Angular-ui Bootstrap for my application. I use the typeahead directive.
html:
<input type="text" class="pass_code_input" ng-model="SuppPrefix" Typeahead="ddl_item.Text for ddl_item in getData($viewValue)"/>
Controller
function AutoCompleteCtrl($scope,$http, AutoCompleteSrv) {
$scope.getData = function (prefix) {
AutoCompleteSrv.GetAutoComplete("Supplier", prefix).then(function (result) {
var results_arr = [];
angular.forEach(result.data, function (item) {
results_arr.push({ "Val": item.Val, "Text": item.Text });
});
return results_arr
});
};
};
service:
function AutoCompleteSrv($http) {
var _$http = $http;
self = this;
self.GetAutoComplete = function (DataType, Prefix) {
var promise = _$http({
method: "GET",
url: 'api/AutoComplete',
params: { 'DataType': DataType, 'Prefix': Prefix }
}).success(function (data, status, headers, config) {
}).error(function (data, status, headers, config) {
});
return promise;
};
};
I do recieve the data from server, but I can't display it on the screen. When I run debugger in chrome dev tools, I get the next error:
TypeError: Cannot read property 'length' of undefined
at http://localhost:52145/js/libs/ui-bootstrap-tpls-0.11.0.min.js:13:12650
at m.promise.then.u (http://localhost:52145/js/angular/angular.min.js:97:280)
at m.promise.then.u (http://localhost:52145/js/angular/angular.min.js:97:280)
at http://localhost:52145/js/angular/angular.min.js:98:417
at h.$eval (http://localhost:52145/js/angular/angular.min.js:108:482)
at h.$digest (http://localhost:52145/js/angular/angular.min.js:106:62)
at h.$apply (http://localhost:52145/js/angular/angular.min.js:109:287)
at HTMLInputElement.l (http://localhost:52145/js/angular/angular.min.js:133:191)
at http://localhost:52145/js/angular/angular.min.js:31:32
at q (http://localhost:52145/js/angular/angular.min.js:7:386)
I've searched for solution in multiple places, like that, and also followed step by step the instructions in the bootstrap ui home page. What did I do wrong?
I just ran into this and just solved it. The key here is that in the example given on the angular site they "return" the $http results. That makes it confusing to look at but ultimately that is the return that matters. So in your case you are setting a variable to that return value so the return never gets returned. When your code is formatted in this way you will need to do 2 things to change it: The first is that the "return" statement is in the wrong place. The second is that the declaration for the returned value is also in the wrong place. Here is the non-working code from the example:
.....
then(function(res){
var addresses = [];
angular.forEach(res.data.results, function(item){
addresses.push(item.formatted_address);
});
return addresses;
});
Here is how I changed it to get it working.
var addresses = []
....
then(function(res){
angular.forEach(res.data.results, function(item){
addresses.push(item.formatted_address);
});
});
return addresses;
This becomes more clear if you do not use the "then" but instead use the "success" and "error" functions. It then becomes obvious where the return statement should lie and where the returned value declaration should be. Writing the code that way and getting it to work is how I figured out the problem. NOTE that you should clear out the addressses value in the "then" function or else it will just keep appending more and more values.
I was also having this problem.
For me I had my controller calling my service, which was then talking to the api to get my data.
Even though getting the data was working (I was able to see this with a console.log) nothing was being displayed on the webpage to select from, and I was getting the
cannot read property length of undefined
error.
Finally I realized I needed to return my call to the service.
//controller with code NOT working
vm.getData = function(val, ep) {
myService.getData(val, ep)
.then(function(data){
return data
});
};
//service
this.getData = function(val, ep) {
return $http({
//do http call here
})
.then(function(data) {
//do what's needed with the data here
return data
});
};
the fix that got this working:
//controller with code WORKING
vm.getData = function(val, ep) {
return myService.getData(val, ep)
.then(function(data){
return data
});
};
So again, I just needed to return my call to the service and then the typeahead worked as expected and no more error!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With