Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

AngularJS - searching and filtering an array issue.

So I am experimenting with AngularJS and ran into a small issue. I would like to write a code that does something similar to a google search. You start typing into an input field, iterate through an array and push the results into an empty array.

Now the thing is that the code works except for one issue. When the page is loaded the empty array thats supposed to hold the search results is filled with the content of the original array holding the information. But I would like to be it empty when the page loads. Can anyone help me fix the problem?

Here is the code:

<!DOCTYPE html>
<html>

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.3/angular.min.js"></script>
    <script>
        var app = angular.module('myApp', []);
        app.controller('myController', ['$scope', function($scope){
            $scope.names = ["Gabriel", "Angel", "Adam", "Marie", "Annie"];
            $scope.searchName = "";
            $scope.searchLength = 0;
            $scope.searchResults = [];
            $scope.$watch('searchName', function(){
                $scope.searchLength = $scope.searchName.length;
            })
            $scope.$watch('searchLength', function(){
                $scope.searchResults = [];
                for(var i=0; i < $scope.names.length; i++){
                    if($scope.names[i].substring(0,$scope.searchLength).toLowerCase() === $scope.searchName.toLowerCase()){
                        $scope.searchResults.push($scope.names[i]);
                    }
                }
            })
        }]);
    </script>
</head>

<body ng-app="myApp">

    <div ng-controller="myController">
        <input type="text" ng-model="searchName">
        <p>{{searchName}}</p>
        <p>{{searchResults}}</p>
    <div>

</body>


</html>

2 Answers

Andrew Chalkley
STAFF
Andrew Chalkley
Treehouse Guest Teacher

How about adding a clause like $scope.searchLength > 0

Thanks for the answer, in the end (for the project) instead of using "$watch" I did your suggestion (checking the length of the search).

$scope.filterListOfCompanyNames = function(){
    getCompanyNames.filterList($scope.formForSearchingCompanyData.companyName, function(data){
    $scope.filteredListOfCompanyNames = data;
})};

And the corresponding factory.

companiesFactory.factory("getCompanyNames", function($http){

    var cachedData;

    function getData(callback){
        if(cachedData){
            callback(cachedData);
        } else {
            $http.get('src/app-features/companies/fetch_company_names.php').success(function(data){
                cachedData = data;
                callback(data);
            });
        }
    }

    function filterData(inputCompanyName, callback){
        var listOfCompanyNames = [];
        var filteredListOfCompanyNames = [];
        getData(function(data){
            listOfCompanyNames = data;
            if(inputCompanyName.length != 0){
                for(var i=0; i < listOfCompanyNames.length; i++){
                    if(listOfCompanyNames[i].company_name.substring(0,inputCompanyName.length).toLowerCase() === inputCompanyName.toLowerCase()){
                        filteredListOfCompanyNames.push(listOfCompanyNames[i].company_name);
                    }
                }
            }
        });
        callback(filteredListOfCompanyNames);
    }

    return {
        filterList: filterData
    }

})

I'm not sure if you need to programmatically iterate through the array and find the search value, but there's a built in AngularJS way of handling searching of an array that's auto-magic.

Provide a search field, bind it to a watched variable by using the ng-model='your-watched-search-variable-name', and then use ng-repeat to iterate through the array and display all the values filtered on the searchName binding - it will auto-magically reduce the displayed list as you type.

You do need to represent your names as objects, not array literals, so something like this:

        $scope.names = [{firstName: "Gabriel"}, {firstName: "Angel"}, {firstName: "Adam"}, {firstName: Marie"}, {firstName: "Annie"}];
<input ng-model="searchName" type="text"placeholder="Search" />

<ul>
   <li ng-repeat="name in names | filter: searchName">
          {{name.firstName}}
   </li>
</ul>

There's good documentation / examples here: https://docs.angularjs.org/tutorial/step_03