1

I am learning to do autocomplete using pure AngularJS and the below code which I have copied from YouTube video.

I am stuck on this particular part:

Controller

myApp.controller("myWeatherContrl", function ($scope, weatherService) {
$scope.title = "Weather App";
weatherService.getCities().then(function (response) {
    $scope.data = response;
    //console.log("Say Hi", $scope.data);
})

$scope.complete = function (string) {
    var output = [];
    angular.forEach($scope.data, function (city) {
        if (city.toLowerCase().indexOf(string.toLowerCase()) >= 0) {
            output.push(city);
        }
    });
    $scope.filterCity = output;
};
$scope.fillTextbox = function(string){
    $scope.city = string;
    $scope.hidethis = true;
};
});

Service

myApp.service("weatherService", ['$http', '$q', function ($http, $q) {
return {
    getCities: function () {
        return $http.get('data/data.json');
        }
   };
}]);

HTML (Directive)

<div class="input-group">
<input type="text" id="city" ng-keyup="complete(city)" placeholder="Enter City Name" class="form-control" ng-model="city"/>
<ul class="list-group">
    <li class="list-group-item" ng-model="hidethis" ng-hide="hidethis" ng-click="fillTextbox(citydata)" ng-repeat="citydata in filterCity">
        {{citydata}}
    </li>
</ul>

index.html

<!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8" />
 <title>Weather App</title>    
   <link href="Content/bootstrap.min.css" rel="stylesheet" />
  <link href="style/style.css" rel="stylesheet" />
  </head>
 <body ng-app="myWeatherApp" ng-controller="myWeatherContrl">
 <div class="container">  
    <label ng-cloak>{{title}}</label>
     <ui-view></ui-view>
 </div>    
 <script src="Scripts/angular.min.js"></script>
 <script src="Scripts/angular-ui-router.min.js"></script>
 <script src="app.js"></script>    
 <script src="Scripts/controller/weathercntrl.js"></script>
 <script src="Scripts/service/weather.js"></script>
 </body>
 </html>

I am getting an error as city.toLowerCase is not a function.

3
  • 1
    your code is incomplete. where are you calling getCities function? Commented Aug 22, 2017 at 19:31
  • I have updated my code Commented Aug 22, 2017 at 19:33
  • You need to make sure $scope.data is an array of strings, as toLowerCase() is a prototype of String. You are getting the error "city.toLowerCase is not a function" because at the point of executing the angular.forEach method, the typeof city in your loop is not "string". Commented Aug 22, 2017 at 19:35

2 Answers 2

1

Try this:

var myApp = angular.module("myApp", []);
myApp.controller("myWeatherContrl", function($scope, weatherService) {
  $scope.title = "Weather App";
  
  $scope.obj = {};
  $scope.obj.data = [];
  weatherService.getCities().then(function(response) {
    angular.forEach(response.data, function(state) {

      angular.forEach(state, function(city) {

        if (typeof city === "string") {
          $scope.obj.data .push(city);
        }
      });
    });

    console.log("Say Hi", $scope.data);
  })

  $scope.complete = function(string) {
    var output = [];
    if (string.length >= 3) {
      angular.forEach($scope.obj.data , function(city) {
        if (city.toLowerCase().indexOf(string.toLowerCase()) >= 0) {
          output.push(city);
        }
      });
    }
    $scope.filterCity = output;
  };
  $scope.fillTextbox = function(string) {
    $scope.city = string;
    $scope.hidethis = true;
  };
});
myApp.service("weatherService", ['$http', '$q', function($http, $q) {
  return {
    getCities: function() {
      return $http.get('https://api.myjson.com/bins/pufq5');
    }
  };
}]);
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

<body>

  <div ng-app="myApp" ng-controller="myWeatherContrl">
    <div class="input-group">
      <input type="text" id="city" ng-keyup="complete(obj.city)" placeholder="Enter City Name" class="form-control" ng-model="obj.city" />
      <ul ng-if="obj.data.length>0" class="list-group">
        <li style="cursor:pointer" class="list-group-item" ng-click="obj.city = citydata;obj.data={};" ng-repeat="citydata in filterCity track by $index">
          {{citydata}}
        </li>
      </ul>
    </div>
</body>

Sign up to request clarification or add additional context in comments.

7 Comments

thanks @Gaurav the error is not coming but i am not getting the autocomplete in my view
it means your json is in different format. please share your json structure.
do you want to search for state for city?
only City not for state
@Vivz thanx bro. i didn't saw that. fixed it :-)
|
0

When doing weatherService.getCities().then(function (response)..., the response must not be returning a list of strings.

This means that when you call angular.forEach($scope.data, function (city) { the city variable is not being populated with a string.

Add console.log(city) in your forEach loop to assist debugging.

1 Comment

I think if you add snippets instead of just code tags, it'll have better readability, even if the snippets are just a couple of lines each.

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.