0

So this works with static data, but when I push data with a $http this autocomplete does not work. The data pushes to the empty array of airport_list but something is happening when I try to use airport_list in for the autocomplete. Not sure what is is. I can only find answers which pertain to static data.

This is updated per everyones help.

Here is the controller

 app.controller('selectCtrl', function($scope, $http) {
   $scope.airport_list = null;
    $http({
     url: 'someUrl.com',
     method: 'GET'
    })
    .then((response) => {
      angular.forEach(response.data.airports, function(value, key) {
      $scope.airport_list = response.data.airports;
    })
    $scope.airports = $scope.airport_list;
  });
  $scope.selectAirport = function(string) {
   $scope.airport = string;
   $scope.hidelist = true;
 };
})

Here is the template

<div class="control">
  <div>
    <input
      type="text"
      name="airport"
      id="airport"
      ng-model="airport"
      ng-change="searchFor(airport)"
      placeholder="From..."
    />
    <div class="airport-container-dropdown" ng-hide="hidelist">
      <div 
        class="airport-list" 
        ng-repeat="airport in airports" 
        ng-click="selectAirport(airport)"
      >
        {{ airport.name }}
      </div>
    </div>
  </div>
</div>

I really would like to do this without using bootstrap typeahead. Thank you for looking at this.

I have made changes as recommended by below answers and the $http request is feeding into the autocomplete as a whole list but searching by name does not work and clicking on name sets [object, object]

this would be the code which is specific to that functionality.

$scope.searchFor = function(string) {
$scope.hidelist = false;
const output = [];
angular.forEach($scope.airport_list, function(airport) {
  if (airport[0].toLowerCase().indexOf(string.toLowerCase(airport)) >= 
  0) {
    output.push(airport);
  }
});
$scope.airports = output;
};
$scope.selectAirport = function(string) {
  $scope.airport = string;
  $scope.hidelist = true;
};
3
  • try using a different intermediate in the ng-repeat from the ng-model (i.e. use ng-repeat="port in airports". Commented Dec 3, 2017 at 16:18
  • if I use {{ port }} instead of {{ port.name }} it just list the whole json response. port.name shows nothing? No idea Commented Dec 3, 2017 at 16:35
  • the whole json response? can you edit your question and show what that looks like? Commented Dec 3, 2017 at 16:36

1 Answer 1

1

Try this:

$scope.airport_list = response.data.airports;

What I am seeing is that you have an array: $scope.airport_list = [];

When you make your http request, you push what I would understand to be an array of airports into that array. So you end up with your airport array from the backend at the first position of $scope.airport_list, vs. $scope.airport_list being the actual list.

For your search method, you should change the following:

In your HTML:

ng-change="searchFor(airport.name)"

In your JS:

I've renamed your function and changed the input variable to be more clear. You were passing in a full airport, but treating it as a string. You need to compare your provided airport name to that of the airports in the array. So you iterate over the array, and compare each element's name property to what you pass in.

$scope.searchFor = function(airportName) {
    $scope.hidelist = false;
    const output = [];
    angular.forEach($scope.airport_list, function(airport) {
        if (airport.name.toLowerCase() === airportName) {
            output.push(airport);
        }
    });
    $scope.airports = output;
    console.log($scope.airports);
};

I have provided minimal changes to your code to implement this, however I suggest you look at this SO post to filter drop down data more appropriately.

Angularjs Filter data with dropdown

If you want to simply filter out what is displayed in the UI, you can try this in your HTML template. It will provide a text field where you supply a partial of the airport name. If at least one character is entered in that box, the list will display on the page, with the appropriate filtering applied. This will avoid having to call functions on change, having a separate array, etc.

<input type="text" name="airport" id="airport" ng-model="airportSearch.name" placeholder="From..." />

<div class="airport-container-dropdown" ng-hide="!airportSearch.name">
  <div class="airport-list"
      ng-repeat="airport in airport_list | filter:airportSearch"
      ng-click="selectAirport(airport)">
    {{ airport.name }}
  </div>
</div>
Sign up to request clarification or add additional context in comments.

6 Comments

You are correct, I removed $scope.airport_list = [], repleaced it with $scope.airport_list = null then for the $http request did $scope.airport_list = response.data.airports. The airports are displaying by name in the autocomplete but search by typing name does not return anything.
I have made changes and updated what is fixed and what is still not working.
I updated and added changes for your search function. The function you have is taking an airport object, but treating it as a string.
If you want to have more help, creating a plnkr.co would help us help you.
I put in a sample of how you might filter in the UI as well without making calls to controller methods on the text-box change. After looking for a while, that looks more in line with what you are trying to do, without having extra functions, arrays, etc.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.