Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs bootstrap typeahead not working: Error: [filter:notarray]

I need to fetch suggest options using typeahead making a http call

$scope.getlist = function getListofNames(name) {
 return $http({
   method: 'GET',
     url: '/v1/'+name,
     data: ""
 }).then(function(response){

     if(response.data.statusMessage !== 'SUCCESS'){
         response.errorMessage = "Error while processing request. Please retry."
           return response;
     }

         else {
           return response.data.payload;
         }

       }, function(response){
       response.errorMessage = "Error while processing request"
           return response;
       }
       );
}

response.data.payload is an array of objects , It is fetched successfully but I am getting this error Error: [filter:notarray] http://errors.angularjs.org/1.4.5/filter/notarray?

Note : I am using angular 1.4.5 and Bootstrap v3.1.1

like image 668
deepThought Avatar asked Sep 13 '15 18:09

deepThought


1 Answers

I'm guessing your typeahead markup looks like this:

<input [...] typeahead="item in getItems($viewValue) | filter: $viewValue">

Why it is not working:

The problem occurs when the array of items is fetched asynchronously. In your case the getItems function is called getListofNames, and your items are indeed fetched asynchronously, due to the call to $http. Therefore at the time the error occurs, getListofNames() is still an unresolved promise object, not yet an array of names.

How could you make that work:

Remove the filter from the template. You should filter the array before returning it in getItems. Ideally, you want to do the filtering server-side. Indeed, the server receives the substring typed by the user (this is the $viewValue argument), and therefore it has all the data to filter the array. That would prevent returning all the elements and make the response shorter. Alternatively, you could filter client-side in the callback of the promise:

$scope.getList = function getListofNames(name) {
    return $http(...}).then(
        function(response){
            // filter response.data.payload according to 
            // the 'name' ($viewValue) substring entered by the user
            return filteredArray; // <- no need to pipe a filter in the template anymore
        }
    );
};
like image 109
Michael P. Bazos Avatar answered Oct 18 '22 00:10

Michael P. Bazos