var app = angular.module('weatherApp', []);
app.controller('weatherCtrl', ['$scope', 'weatherService', function($scope, weatherService) {
function fetchWeather(zip) {
weatherService.getWeather(zip).then(function(data){
$scope.place = data;
});
}
fetchWeather('84105');
$scope.findWeather = function(zip) {
$scope.place = '';
fetchWeather(zip);
};
}]);
app.factory('weatherService', ['$http', '$q', function ($http, $q){
function getWeather (zip) {
var deferred = $q.defer();
$http.get('https://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20weather.forecast%20WHERE%20location%3D%22' + zip + '%22&format=json&diagnostics=true&callback=')
.success(function(data){
deferred.resolve(data.query.results.channel);
})
.error(function(err){
console.log('Error retrieving markets');
deferred.reject(err);
});
return deferred.promise;
}
return {
getWeather: getWeather
};
}]);
<!DOCTYPE html>
<html ng-app="weatherApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link data-require="jasmine@*" data-semver="2.0.0" rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
<script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
<script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
<script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js" data-semver="1.2.16" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script data-require="angular-mocks" data-semver="1.2.16" src="https://code.angularjs.org/1.2.16/angular-mocks.js"></script>
<script data-require="bootstrap@*" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="app.js"></script>
<script src="appSpec.js"></script>
<script src="jasmineBootstrap.js"></script>
</head>
<body ng-controller="weatherCtrl">
<form>
<div class="form-group">
<input class="form-control" type="number" ng-model="zip" placeholder="e.g. 84105" />
<input class="btn btn-default" type="submit" value="Search" ng-click="findWeather(zip)" />
</div>
</form>
<p ng-show="zip">Searching the forecasts for: {{zip}}</p>
<div>
<h1>Forecast For {{ place.location.city }}</h1>
<a ng-click="findWeather('84106'); zip = ''">reset</a>
<h3>
<img class="img-thumbnail forecast-img" src="http://l.yimg.com/a/i/us/we/52/{{place.item.condition.code}}.gif" />
Current: {{ place.item.condition.text }} | {{ place.item.condition.temp }}°</h3>
<div class="row">
<div class="col-xs-6" ng-repeat="forecast in place.item.forecast">
<div class="panel panel-primary">
<div class="panel-heading">
<h4>
<img class="img-thumbnail forecast-img" src="http://l.yimg.com/a/i/us/we/52/{{forecast.code}}.gif" />
<strong>{{ forecast.date }}</strong>
</h4>
</div>
<div class="panel-body">
<p>{{ forecast.text }}</p>
<p>H: {{ forecast.high }}° | L: {{ forecast.low }}°</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
/* Put your css in here */
body {
padding: 10px;
}
a {
cursor: pointer;
}
.form-control {
float: left;
margin-right: 10px;
width: 70%;
}
.forecast-img {
margin-right: 10px;
width: 45px;
}
A small weather app using AngularJS $http requests.
===================================================
See blog post at http://austinknight.net/weather-app-with-angular-js/
Austin Knight // [@austinknight](http://twiter.com/austinknight) // http://austinknight.net
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 250;
/**
Create the `HTMLReporter`, which Jasmine calls to provide results of each spec and each suite. The Reporter is responsible for presenting results to the user.
*/
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
/**
Delegate filtering of specs to the reporter. Allows for clicking on single suites or specs in the results to only run a subset of the suite.
*/
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
/**
Run all of the tests when the page finishes loading - and make sure to run any previous `onload` handler
### Test Results
Scroll down to see the results of all of these specs.
*/
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
//document.querySelector('.version').innerHTML = jasmineEnv.versionString();
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
describe('Controller: weatherCtrl', function() {
var $scope, ctrl, $httpBackend, weatherService;
//This is not the complete data we get, it's just a fake object
var weatherObject = {
"query":{
"results":{
"channel":{
"location":{
"city":"Salt Lake City",
"country":"US",
"region":"UT"
}
}
}
}
};
var resolvedData = {
"location":{
"city":"Salt Lake City",
"country":"US",
"region":"UT"
}
};
var zip = 84105;
beforeEach(module('weatherApp'));
beforeEach(inject(function($rootScope, $controller, $httpBackend, weatherService) {
$scope = $rootScope.$new();
$httpBackend = $httpBackend;
weatherService = weatherService;
$httpBackend.when("GET", 'https://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20weather.forecast%20WHERE%20location%3D%22' + zip + '%22&format=json&diagnostics=true&callback=').respond(weatherObject);
$httpBackend.when("GET", 'https://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20FROM%20weather.forecast%20WHERE%20location%3D%2284060%22&format=json&diagnostics=true&callback=').respond(weatherObject);
ctrl = $controller('weatherCtrl', {
$scope: $scope,
weatherService: weatherService
});
$httpBackend.flush();
}));
afterEach(inject(function($httpBackend){
$httpBackend = $httpBackend;
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
}));
describe('using', function(){
it('should get some weather data for the default zip code 84106', function() {
$scope.$digest();
expect($scope.place).toEqual(resolvedData);
});
it('should get some weather data for any given valid zip code', function() {
$scope.$digest();
$scope.findWeather('84060');
expect($scope.place).toEqual(resolvedData);
});
});
});