There are several reasons you may wish to add a basic weather forecast to a mobile application. Recently I added weather forecasts to a customer’s LOB app to allow technicians to anticipate weather at multiple job sites. This allows them to better plan for conditions over the course of several days.
In this tutorial, I will build a basic angular service to get weather forecasts using the Weather Underground API.
- Create an API Key and store this key in your application’s configuration.
- Create an angular service to retrieve the forecast data. Include your API Key in the calls.
angular.module('WundergroundService', []) .factory('WundergroundService', function ($q, $http, Configuration) { var factory = {}; wunderground_api_key = Configuration.wunderground_api_key; factory.getForecast = function (lat, lng) { return $q(function (resolve, reject) { var url = 'http://api.wunderground.com/api/' + wunderground_api_key + '/forecast/q/' + lat + ',' + lng + '.json'; var parameters = {} var successCallback = function (response) { resolve({ "success": true, "message": "", "title": "Success", "data": response }); }; var errorCallback = function (response) { var message = response == null ? ConfigMaster.UnknownError : response.error_description; resolve({ "success": false, "message": message, "title": "Error", "data": null }); }; $http({ method: 'GET', url: url, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, transformRequest: function (obj) { var str = []; for (var p in obj) str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p])); return str.join("&"); }, params: parameters }).success(successCallback).error(errorCallback) }) } return factory; });
- Include the service’s js file in your application’s Index.html
... <script src="js/services/wunderground-service.js"></script> ...
- In your app.js, include the service.
var app = angular.module('app', ['ionic', 'ngCordova', 'Configuration', ... 'WundergroundService'... ]) ...
- In your controller, add a method to call getForecast and store the result in a $scope variable.
getForecast($scope.Location.Latitude, $scope.Location.Longitude, false); getForecast = function (lat, lng, isretry) { var _weather = [] if (ConnectivityMonitor.isOnline()) { WundergroundService.getThreeDayForecast(lat, lng).then(function (r) { if (r.success) { if (r.data.response.error) { if (!isretry) { // retry in 0.5 seconds if there was an error setTimeout(function () { getForecast(lat, lng, true); }, 500); } $scope.hasWeather = false; } else { angular.forEach(r.data.forecast.simpleforecast.forecastday, function (forecastday) { if (forecastday.period <= 5) { _weather.push(forecastday); } }); $scope.weather = _weather; $scope.hasWeather = true; } } }); } else { $scope.hasWeather = false; $scope.weather = null; } }
- In your view, display the result using a repeater and a template.
... <div class="col" ng-repeat="day in weather" ng-include="'templates/partial/forecast.html'"></div> ...
<span class="weather-title-day" ng-bind="day.date.weekday"></span> <br><img ng-src="{{day.icon_url}}" alt="{{day.conditions}}"> <br>H: <span class="weather-forecast" ng-bind="day.high.fahrenheit"></span>° / L: <span class="weather-forecast" ng-bind="day.low.fahrenheit"></span>° <br><span class="weather-forecast" ng-bind="day.conditions"></span>
Your view will now display a formatted weather forecast, using the images from WeatherUndreground’s simple forecast data.