Angular js, weather api search city and using enter key

2.3k Views Asked by At

So the code allows me to show low and high temperature using the openweather api data. I can see the data perfectly, if i declare the value of the city in the input (ex: value ="houston")

but i want a function that takes the value i entered and when i hit the enter key, the data displays.

This way i can see the data of any city i choose. Below is my code, runs perfect if i don't use the enterkey function inside ng-keydown and declare a value instead. so it must the way i use enterkey function in js file .

var app = angular.module('myapp', []);

app.controller('DemoCtrl', function($http) {

    var ctrl = this;

    var URL = 'http://api.openweathermap.org/data/2.5/forecast/daily';
    var city = document.getElementById("search_box").value;
    var request = {
        method: 'GET',
        url: URL,
        params: {
            q: city,
            mode: 'json',
            units: 'imperial',
            cnt: '7',
            appid: 'd20b7e069e7858118979c0ed0b36f8b5'
        }
    }

    function enterkey() {
        var enterk = event.keyCode || event.which;

        if (enterk == 13) {



    $http(request)
        .then(function (response) {
            ctrl.data = response.data;

            console.log(ctrl.data);
        })

}}
})
   

<!DOCTYPE html>

<html>
<head>
  <link rel="stylesheet" type="text/css" href="../css/weatherangu.css">
  <meta charset="utf-8">
  <title>Angular JS</title>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.js"></script>

</head>
<body ng-app="myapp">

  
  <div id="content" ng-controller="DemoCtrl as ctrl">

    <img id="w_pic" src="../images/7day.png">
    <input type="text" id="search_box" placeholder="Enter City Name Here.." ng-keydown="enterkey()">

    <div id="weather_data">
       <h1 class="zero">{{ ctrl.data.list[0].temp.max| json }}</h1><br>
       <h1 class="zero">{{ ctrl.data.list[0].temp.min| json }}</h1>

      <h1 class="one">{{ ctrl.data.list[1].temp.max| json }}</h1><br>
      <h1 class="one">{{ ctrl.data.list[1].temp.min| json }}</h1>

      <h1 class="two">{{ ctrl.data.list[2].temp.max| json }}</h1><br>
      <h1 class="two">{{ ctrl.data.list[2].temp.min| json }}</h1>

      <h1 class="three">{{ ctrl.data.list[3].temp.max| json }}</h1><br>
      <h1 class="three">{{ ctrl.data.list[3].temp.min| json }}</h1>

      <h1 class="four">{{ ctrl.data.list[4].temp.max| json }}</h1><br>
      <h1 class="four">{{ ctrl.data.list[4].temp.min| json }}</h1>

      <h1 class="five">{{ ctrl.data.list[5].temp.max| json }}</h1><br>
      <h1 class="five">{{ ctrl.data.list[5].temp.min| json }}</h1>

      <h1 class="six">{{ ctrl.data.list[6].temp.max| json }}</h1><br>
      <h1 class="six">{{ ctrl.data.list[6].temp.min| json }}</h1>

              </div>
  </div>
  <script src = "../js/weatherangu.js"></script>

</body>
</html>

2

There are 2 best solutions below

3
On

You don't need anything extra to use the enter key. Just enclose the input in a form with a submit input. Then use ng-submit to show the details when the enter key is pressed. Also, the functions you're calling from the view, need to be attached to the $scope. And with angular, you don't need to use DOM functions in the controllers, use ng-model instead.

HTML

<form action="" method="get" ng-submit="submitForm()">
  <input ng-model="cityName" type="text" id="search_box" placeholder="Enter City Name Here..">
  <input type="submit" style="display:none"/>
</form>

JS

app.controller('DemoCtrl', function($http) {

    var ctrl = this;

    var URL = 'http://api.openweathermap.org...';
    var request = {
        method: 'GET',
        url: URL,
        params: {
            //use ng-model instead of getElementById
            q: ctrl.cityName, 
            mode: 'json',
            ...
        }
    }

    ctrl.submitForm = function() {
        $http(request)
            .then(function (response) {
                ctrl.data = response.data;
                console.log(ctrl.data);
            })
    }
})

I haven't tested it, but you should get the idea.

0
On

So, after getting suggestions from the members i was able to connect the input value to the value of the city by ng-model, this will create a two-way data-binding. I also had to manually use $watch to look for input value changes and re run the function to change the data dynamically as i type in the city name. If anyone finds any other better,efficient or recommended way of doing this. Please feel free to comment.

var app = angular.module('myapp', []);

app.controller('DemoCtrl', function($http,$scope) {

    var ctrl = this;

    var URL = 'http://api.openweathermap.org/data/2.5/forecast/daily';
    //var cityName = document.getElementById("search_box").value;


    $scope.request = {
        method: 'GET',
        url: URL,
        params: {
            q: 'london',
            mode: 'json',
            units: 'imperial',
            cnt: '7',
            appid: 'd20b7e069e7858118979c0ed0b36f8b5'
        }
    }
function test() {


    $http($scope.request)
        .then(function (response) {

            ctrl.data = response.data;
            console.log(ctrl.data);
        })
}
test();

    $scope.$watch('request.params.q',function () {

        test();

    })


})
<!--<!DOCTYPE html>
<html >
<head>
 <link rel="stylesheet" type="text/css" href="../css/weatherangu.css">
 
  <title></title>
</head>
<body ng-app="wapp">
  
 
 
 <input type="text" id="searchbox" placeholder="Type City Name Here.." onkeydown="enterkey()" >
 
 <div id="posterdiv" ng-controller = "ctrl as vm">

  <p> {{vm.data | json}}</p>

 </div>
 
 
 
 
 
 
 
 

 <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.js"></script>
 
<script src = "../JavaScript/weatherangu.js"></script>
 
</body>
</html>-->

<!DOCTYPE html>

<html>
<head>
  <link rel="stylesheet" type="text/css" href="../css/weatherangu.css">
  <meta charset="utf-8">
  <title>Angular JS</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>

</head>
<body ng-app="myapp">

  
  <div id="content" ng-controller="DemoCtrl as ctrl">

    <img id="w_pic" src="../images/7day.png">


   <!--<form action="" method="get" ng-submit="submitform()">- -->
    <!--<input  type="text" ng-model="$ctrl.request.params.q" id="search_box" placeholder="Enter City Name Here..">-->
     <!--<input type="submit" style="display:none"/>-->
  <!--</form>-->


    <input  type="text"   ng-model="request.params.q" id="search_box" placeholder="Enter City Name Here..">


    <div id="weather_data">
{{
       <h1 class="zero">{{ ctrl.data.list[0].temp.max| json }}</h1><br>
       <h1 class="zero">{{ ctrl.data.list[0].temp.min| json }}</h1>

      <h1 class="one">{{ ctrl.data.list[1].temp.max| json }}</h1><br>
      <h1 class="one">{{ ctrl.data.list[1].temp.min| json }}</h1>

      <h1 class="two">{{ ctrl.data.list[2].temp.max| json }}</h1><br>
      <h1 class="two">{{ ctrl.data.list[2].temp.min| json }}</h1>

      <h1 class="three">{{ ctrl.data.list[3].temp.max| json }}</h1><br>
      <h1 class="three">{{ ctrl.data.list[3].temp.min| json }}</h1>

      <h1 class="four">{{ ctrl.data.list[4].temp.max| json }}</h1><br>
      <h1 class="four">{{ ctrl.data.list[4].temp.min| json }}</h1>

      <h1 class="five">{{ ctrl.data.list[5].temp.max| json }}</h1><br>
      <h1 class="five">{{ ctrl.data.list[5].temp.min| json }}</h1>

      <h1 class="six">{{ ctrl.data.list[6].temp.max| json }}</h1><br>
      <h1 class="six">{{ ctrl.data.list[6].temp.min| json }}</h1>
}}
     </div>
  </div>

  <script src = "../js/weatherangu.js"></script>

</body>
</html>