Simple AngularJS application with Yahoo Weather API
After lot of ground work now we can easily start writing our AngularJS application. Let me just give you a brief about what you are going to build. We are going to develop a simple weather forecasting application with Yahoo API. There will be only one screen with one input box, you can enter zip code to see forecast of next 5 days. I am going to use Yahoo weather API to get forecasting data.
So let’s start writing body of index.html.
<body ng-app="myApp" ng-controller="listCtrl">
<center>
<div>
Weather Forecast - Enter zip code and click get forecast
</div>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div ng-view></div>
<hr/>
<div>Angular seed app: v<span app-version></span></div>
</center>
<!-- In production use: <script src="//ajax.googleapis.com/ajax/libs/angularjs/x.x.x/angular.min.js"></script>-->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="app.js"></script>
<script src="list/listController.js"></script>
<script src="components/version/version.js"></script>
<script src="components/version/version-directive.js"></script>
<script src="components/version/interpolate-filter.js"></script>
<script src="services/listService.js"></script>
</body>
Explanation
Observe above HTML properly and you will notice few new attributes starting with ng-
These are angular directives which informs AngularJS framework which DOM element to bind a mentioned behavior. For now let’s continue with the same example and you will understand the purpose of the directive.
Details of angular directives used in above markup are;
ng-app – We use this directive to auto-bootstrap the application
ng-controller – We use this to attach a controller class to specific UI element form view
ng-view – This directive helps to render the template which is attached to particular controller class
Note – please check the path of all js files mentioned in above code. You may need to create some directories like list, services. Such directories are not a part of the boiler plate, List is one of our screen so it’s always better to keep its controller and its template in same directory name “list”.
Now we need to write Angular service which will pull data from Yahoo API.
'use strict';
angular.module('myApp.services', []).
factory('weatherService', function($http) {
var API = {};
API.getForecast = function(countryZip)
{
return $http({
method: 'GET',
url: 'https://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20weather.forecast%20WHERE%20location%3D%22'+countryZip+'%22&format=json&diagnostics=true&callback='
});
}
return API;
});
An Angular service is an injectable object. It is a code block where we can write common logic which needs to be shared across application. For example in our application we need to make an AJAX call and get the data from Yahoo API. This part of code should not be reused and thus we are writing it in angular service and later on we will inject this service in one of our controller. This method of writing code is called as dependency injection.
Code explanation – You can see we have written a method in this service termed as – getForecast. Job of this method is to make REST call to Yahoo API and then return the response object.
AngularJS provides $http service to make AJAX calls to server. You can see we have injected $http method in our factory service. Once it is injected we can make use of this method to make a call. The getForecast method is self-explanatory.
Time to introduce first controller of the application.
'use strict';
angular.module('myApp.list', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when( '/list', {
templateUrl: 'list/list.html',
controller: 'listCtrl'
});
}])
.controller('listCtrl', ["$scope","weatherService",function($scope, weatherService ) {
$scope.init = function(){
$scope.forecastList = [];
$scope.nameFilter = null;
$scope.countryZip = 10001; // new york
$scope.getData();
}
$scope.getData =
Function (){ weatherService.getForecast($scope.countryZip).Success(function(response){
$scope.forecastList = response.query.results.channel.item.forecast;
$scope.city = response.query.results.channel.location.city;
$scope.country = response.query.results.channel.location.country ;
});
}
$scope.getForecastFromZip = function(){
$scope.getData();
}
$scope.init();
}]);
In previous steps we completed writing Angular Service, which will fetch required data from API. We have designed this service so that we can inject it in any controller and thus it can be reusable. Now let's see how to inject this service and define the template to display the forecast data.
Check first code block in which I have configured my template list.html with the controller and URL. I will also share how to design this template, for now let’s continue completing this controller.
Init method – This method is used to initialize required variables. You can see I have initialized countryZip variable to 10001, this is New York’s zip code. So when an application loads it always loads with default data for New York.
geData – This method makes use of injected service “weatherService” and its methods to get the data from API. I am calling getForecast method and passing it an argument which is nothing but countryZip. Once the network call for Yahoo Api is complete service will return the response to our controller in response object. We will pick 3 objects from this response, forecast, country, and city. We will now learn how to show these 3 objects with template.
getForecastFromZip – when user enter some zip code and hit submit then this method gets called to get the data for entered zip code.
Let’s write App.js – to bootstrap the application
'use strict';
// Declare app level module which depends on views, and components
angular.module('myApp', [
'ngRoute',
'myApp.list',
'myApp.version',
'myApp.services'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/list'});
}]);
We have just created some angular modules including service and controller. Next step is to inject them in application. I have named my application “myApp”, if you notice in the index.html body tag then you can see same name attached with tag ng-app. Now check app.js to understand how these modules can be added to angular application.
Create Template to display the forecast.
<input type="text" ng-model="countryZip" placeholder="enter zip code..." /> <input type="submit" name="submit" value="get forecast" ng-click="getForecastFromZip();">
<br/>
<br/>
<table border="1" cellpadding="2px;">
<thead>
<tr><th colspan="4">Forecast of - {{city}} ({{country}})</th></tr>
</thead>
<tbody>
<tr ng-repeat="forecast in forecastList">
<td>{{forecast.date}} - ({{forecast.day}})</td>
<td>
{{forecast.text}}
<br/>
High - {{forecast.high}}<br/>
Low - {{forecast.low}}
</td>
</tr>
</tbody>
</table>
We have received data in 3 variables from controller and we have to show these 3 variables in our view.
Search box – check attribute ng-model attached to input box. ng-model=”countryZip”. This is very important step to understand. We have initialized the same variable in controller init method and same is bound here with input box.
Observe the attribute ng-click attached with submit button. It’s bind with getForecastFromZip method. It means that click event of this UI element (submit button) is bind to call getForecastFromZip method of the controller defined with ng-controller. If you are confused with this point then please go through index.html (body tag) .
Forecast of – {{city}} ({{country}}) – Check this line in my template. This is AngularJS way of writing variable value. In controller we have extracted 2 variables i.e. city and country. So if you want to echo them in your view then you simply have to embed them in {{}}.
ng-repeat – very important and most required directive while designing any UI component is ng-repeat. This can be used when you want particular UI element to repeat multiple times. In our example we need to show all records which are fetched from service. My template is based on table so I have to repeat <tr> multiple times. That’s the reason ng-repeat tag is added to <tr> tag and not table.
Now refresh your browser and check. Following is the screenshot of landing page.
Resources:
Angular training in chennai
Angular Official