Build a Handy AS3 Weather App with the Yahoo API
With help from this tutorial you will learn how to use the Yahoo Weather API to obtain and display weather forecasts with AS3.
Final Result Preview
Let's take a look at the final result we will be working towards:
Step 1: Create a New File
I'm assuming you'll use Flash, though you can do this with a Flex or standard AS3 Project.
Open Flash, go to File > New, select Flash File (ActionScript 3.0), then set the size as 320x180px and save the FLA wherever you want.



Step 2: Create a Document Class
Now go to File > New and this time select ActionScript File, then save it as Weather.as in the same folder where your saved your FLA file. Then go back to your FLA, go to Properties and write the name of the ActionScript file in the "Class" space. (For more info on using a document class, read this quick introduction.)






Step 3: Setting Up the Document Class
Go to the ActionScript file and write the code for your document class:
1 |
package{ |
2 |
|
3 |
import flash.display.MovieClip; |
4 |
|
5 |
//the name of the class has to be the same as the file
|
6 |
public class Weather extends MovieClip{ |
7 |
|
8 |
//Constructor: this function has to have the same name as the file and class
|
9 |
public function Weather(){ |
10 |
|
11 |
trace("This is your weather class"): |
12 |
|
13 |
}
|
14 |
}
|
15 |
}
|
Test it and it should trace "This is your weather class" in the output window.
Step 4: Check Out the Yahoo Weather API
Get yourself off to the Yahoo Weather API section of the Yahoo developers site; there you will find some explanations about the Yahoo Weather API.



Step 5: Ask For Your XML
What we need to read in Flash is an XML file, so we need to know how to ask for it, which is pretty simple. You need to think about where you want to know the weather and in what unit (Celsius or Fahrenheit) you want the temperature. Then, you can get XML with this data through this URL:
1 |
var url:String = "http://weather.yahooapis.com/forecastrss" + "?w=" + (location number) + "&u=" + ("c" for celcius or "f" for fahrenheit); |
Step 6: Getting the Location Number
The location number needs to be a WOEID. To find your WOEID, browse or search for your city from the Yahoo Weather home page. The WOEID is in the URL for the forecast page for that city. You can also get the WOEID by entering your zip code on the home page. For example, if you search for Los Angeles on the Weather home page, the forecast page for that city is: http://weather.yahoo.com/united-states/california/los-angeles-2442047/, so the WOEID is 2442047.
Step 7: Understanding the XML
When you request any weather location, what you'll receive is XML like this:
1 |
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"> |
2 |
<channel>
|
3 |
<title>Yahoo! Weather - Los Angeles, CA</title> |
4 |
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Los_Angeles__CA/*http://weather.yahoo.com/forecast/USCA0638_c.html</link> |
5 |
<description>Yahoo! Weather for Los Angeles, CA</description> |
6 |
<language>en-us</language> |
7 |
<lastBuildDate>Mon, 01 Mar 2010 5:47 am PST</lastBuildDate> |
8 |
<ttl>60</ttl> |
9 |
<yweather:location city="Los Angeles" region="CA" country="United States"/> |
10 |
<yweather:units temperature="C" distance="km" pressure="mb" speed="km/h"/> |
11 |
<yweather:wind chill="12" direction="0" speed="0" /> |
12 |
<yweather:atmosphere humidity="80" visibility="16.09" pressure="1018.4" rising="1" /> |
13 |
<yweather:astronomy sunrise="6:22 am" sunset="5:49 pm"/> |
14 |
<image>
|
15 |
<title>Yahoo! Weather</title> |
16 |
<width>142</width> |
17 |
<height>18</height> |
18 |
<link>http://weather.yahoo.com</link> |
19 |
<url>http://l.yimg.com/a/i/us/nws/th/main_142b.gif</url> |
20 |
</image>
|
21 |
<item>
|
22 |
<title>Conditions for Los Angeles, CA at 5:47 am PST</title> |
23 |
<geo:lat>34.05</geo:lat> |
24 |
<geo:long>-118.25</geo:long> |
25 |
<link>http://us.rd.yahoo.com/dailynews/rss/weather/Los_Angeles__CA/*http://weather.yahoo.com/forecast/USCA0638_c.html</link> |
26 |
<pubDate>Mon, 01 Mar 2010 5:47 am PST</pubDate> |
27 |
<yweather:condition text="Fair" code="33" temp="12" date="Mon, 01 Mar 2010 5:47 am PST" /> |
28 |
<description><![CDATA[> |
29 |
<img src="http://activetuts.s3.amazonaws.com/tuts/093_weather/Tutorial/http://l.yimg.com/a/i/us/we/52/33.gif"/><br /> |
30 |
<b>Current Conditions:</b><br /> |
31 |
Fair, 12 C<BR /> |
32 |
<BR /><b>Forecast:</b><BR /> |
33 |
Mon - Mostly Cloudy. High: 20 Low: 10<br /> |
34 |
Tue - AM Clouds/PM Sun. High: 19 Low: 9<br /> |
35 |
<br /> |
36 |
<a href="http://us.rd.yahoo.com/dailynews/rss/weather/Los_Angeles__CA/*http://weather.yahoo.com/forecast/USCA0638_c.html">Full Forecast at Yahoo! Weather</a><BR/><BR/> |
37 |
(provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/> |
38 |
]]></description>
|
39 |
<yweather:forecast day="Mon" date="1 Mar 2010" low="10" high="20" text="Mostly Cloudy" code="28" /> |
40 |
<yweather:forecast day="Tue" date="2 Mar 2010" low="9" high="19" text="AM Clouds/PM Sun" code="30" /> |
41 |
<guid isPermaLink="false">USCA0638_2010_03_01_5_47_PST</guid> |
42 |
</item>
|
43 |
</channel>
|
44 |
</rss><!-- api7.weather.re4.yahoo.com compressed/chunked Mon Mar 1 06:59:00 PST 2010 --> |
(If you want to understand all the XML, please visit http://developer.yahoo.com/weather/.)
For this application what we need is the yweather:location tag, yweather:atmosphere tag and the yweather:forecast tags: the location tag will give us the text for the location, the atmosphere tag will give us the humidity and the forecast tags will give us the temperature for the current and the next day.
Step 8: Parse It
Now that we have a better understanding of all that XML, what we need to do is assign data to variables so that we can use that data to set up our application. For that we need to create some variables and load the XML. This is how you do it (put the code in the relevant places in your document class):
1 |
//This is going to contain all the data from the XML
|
2 |
private var _xmlData:XML; |
3 |
//This is going to be the url of the XML that we will load
|
4 |
private var _xmlURL:String; |
5 |
|
6 |
private function loadXML(xmlURL:String):void { |
7 |
var loader:URLLoader = new URLLoader(); |
8 |
var request:URLRequest = new URLRequest(_xmlURL); |
9 |
|
10 |
loader.load(request); |
11 |
loader.addEventListener(Event.COMPLETE, loadData); |
12 |
}
|
13 |
|
14 |
private function loadData(event:Event):void { |
15 |
_xmlData = new XML(event.currentTarget.data); |
16 |
|
17 |
var yweather:Namespace = new Namespace("http://xml.weather.yahoo.com/ns/rss/1.0"); |
18 |
var day:String = _xmlData.channel.item.yweather::forecast[0].@day; |
19 |
var codeToday:String = _xmlData.channel.item.yweather::forecast[0].@code; |
20 |
var codeTomorrow:String = _xmlData.channel.item.yweather::forecast[1].@code; |
21 |
}
|
Let's go over that lump of code.
You need the _xmlData variable to be defined outside all functions (I've defined it as a private variable) because you will need to get it everywhere in the code, not just within one function.
The first function, loadXML(), loads the XML file into Flash; we use an event listener to check when it's completed, then run loadData().
The loadData() function assigns the received data to the _xmlData variable that we have already created. We use a namespace because that's how Yahoo decided to set up their XML (you can find more about namespaces at livedocs.adobe.com). The other variables in this function extract the information that we want to show in our app from the XML.
(For more info on parsing XML in AS3, check out Dru Kepple's AS3:101 - XML tutorial.)
Step 9: Create Text Fields
Now we need to display that information. To do so we could create text fields in the code and assign a format and the text, but I prefer to use the Flash IDE, to save time. So get creative, we need eight text fields: temperature, humidity, maximum temp and minimum temp for the current day. Then we need maximum temp and minimum temp for the next day, one for the name of the next day and one more that shows the location. They all need to be dynamic text fields so we can assign the info.
Don't forget to give all your textfields instance names; I've chosen temp, humidity, max, min, maxt, mint, tomorrow and state.



Step 10: Display the Info
Now that we've created the text fields, we need to assign the information that we retreived from the XML. For that we need the instance name of each text field and the info that we already have, like this (adding to your existing loadData() function):
1 |
private function loadData(event:Event):void { |
2 |
|
3 |
_xmlData = new XML(event.currentTarget.data); |
4 |
|
5 |
var yweather:Namespace = new Namespace("http://xml.weather.yahoo.com/ns/rss/1.0"); |
6 |
var day:String = _xmlData.channel.item.yweather::forecast[0].@day; |
7 |
var codeToday:String = _xmlData.channel.item.yweather::forecast[0].@code; |
8 |
var codeTomorrow:String = _xmlData.channel.item.yweather::forecast[1].@code; |
9 |
|
10 |
//Assigning the information to the text fields
|
11 |
maxt.text = _xmlData.channel.item.yweather::forecast[1].@high + " °F"; |
12 |
mint.text = _xmlData.channel.item.yweather::forecast[1].@low + " °F"; |
13 |
state.text = _xmlData.channel.yweather::location.@city; |
14 |
humidity.text = _xmlData.channel.yweather::atmosphere.@humidity + " %"; |
15 |
temp.text = _xmlData.channel.item.yweather::condition.@temp + " °F"; |
16 |
max.text = _xmlData.channel.item.yweather::forecast[0].@high + " °F"; |
17 |
min.text = _xmlData.channel.item.yweather::forecast[0].@low + " °F"; |
18 |
|
19 |
switch (day) { |
20 |
case "Sun": |
21 |
tomorrow.text = "Monday"; |
22 |
break; |
23 |
case "Mon": |
24 |
tomorrow.text = "Tuesday"; |
25 |
break; |
26 |
case "Tue": |
27 |
tomorrow.text = "Wednesday"; |
28 |
break; |
29 |
case "Wed": |
30 |
tomorrow.text = "Thursday"; |
31 |
break; |
32 |
case "Thu": |
33 |
tomorrow.text = "Friday"; |
34 |
break; |
35 |
case "Fri": |
36 |
tomorrow.text = "Saturday"; |
37 |
break; |
38 |
case "Sat": |
39 |
tomorrow.text = "Sunday" |
40 |
break; |
41 |
}
|
42 |
}
|
Remember the eight text fields that we created? Now we have to use those names here in the code. That switch statement is because we don't want to show just "Wed", "Thu" or "Fri", we want the entire name.
Step 11: Add Some Style
Right now we have just text; it would be nice to add some icons depending on the weather for that day. So what we need is to create or look for a set of weather icons and assign an icon depending on the weather. We can load one image from Yahoo, but it's not that nice so we'll find our own set. For that, download a set of icons and import them to Flash, then export each one for ActionScript with an appropriate class name:



The icons I'm using are from Garmahis and can be downloaded from garmahis.com. Big thanks to Garmahis for letting us use them!
Step 12: Adding the Icon
Now we have to load the correct icon depending on the weather code that we have in our XML. Just like the names of the days, we can do this with a really big switch... but first we need to create a movie clip to contain the icon.
1 |
private var _weatherToday:MovieClip = new MovieClip; |
2 |
private var _weatherTomorrow:MovieClip = new MovieClip; |
3 |
|
4 |
//below code goes in constructor
|
5 |
addChild(_weatherToday); |
6 |
addChild(_weatherTomorrow); |
7 |
_weatherToday .x = -80; |
8 |
_weatherToday .y = -40; |
9 |
_weatherTomorrow .x = 115; |
10 |
_weatherTomorrow .y = -60; |
And now the icons:
1 |
//this code goes in the loadData() function
|
2 |
switch (codeToday) { |
3 |
|
4 |
case "28": |
5 |
case "3200": |
6 |
case "30": |
7 |
case "44": |
8 |
var weather01:weather01 = new weather01(); |
9 |
_weatherToday.addChild(weather01); |
10 |
_weatherToday.scaleX = 0.7; |
11 |
_weatherToday.scaleY = 0.7; |
12 |
break; |
13 |
|
14 |
case "32": |
15 |
case "34": |
16 |
var weather02:weather02 = new weather02(); |
17 |
_weatherToday.addChild(weather02); |
18 |
_weatherToday.scaleX = 0.7; |
19 |
_weatherToday.scaleY = 0.7; |
20 |
break; |
21 |
|
22 |
case "24": |
23 |
case "25": |
24 |
var weather03:weather03 = new weather03(); |
25 |
_weatherToday.addChild(weather03); |
26 |
_weatherToday.scaleX = 0.7; |
27 |
_weatherToday.scaleY = 0.7; |
28 |
break; |
29 |
|
30 |
case "0": |
31 |
case "1": |
32 |
case "2": |
33 |
case "22": |
34 |
case "36": |
35 |
case "42": |
36 |
case "43": |
37 |
var weather04:weather04 = new weather04(); |
38 |
_weatherToday.addChild(weather04); |
39 |
_weatherToday.scaleX = 0.7; |
40 |
_weatherToday.scaleY = 0.7; |
41 |
break; |
42 |
|
43 |
case "19": |
44 |
case "20": |
45 |
case "21": |
46 |
case "23": |
47 |
case "26": |
48 |
var weather05:weather05 = new weather05(); |
49 |
_weatherToday.addChild(weather05); |
50 |
_weatherToday.scaleX = 0.7; |
51 |
_weatherToday.scaleY = 0.7; |
52 |
break; |
53 |
|
54 |
case "41": |
55 |
case "46": |
56 |
var weather06:weather06 = new weather06(); |
57 |
_weatherToday.addChild(weather06); |
58 |
_weatherToday.scaleX = 0.7; |
59 |
_weatherToday.scaleY = 0.7; |
60 |
break; |
61 |
|
62 |
case "3": |
63 |
case "4": |
64 |
case "37": |
65 |
case "38": |
66 |
case "39": |
67 |
case "45": |
68 |
case "47": |
69 |
var weather07:weather07 = new weather07(); |
70 |
_weatherToday.addChild(weather07); |
71 |
_weatherToday.scaleX = 0.7; |
72 |
_weatherToday.scaleY = 0.7; |
73 |
break; |
74 |
|
75 |
case "31": |
76 |
case "33": |
77 |
var weather08:weather08 = new weather08(); |
78 |
_weatherToday.addChild(weather08); |
79 |
_weatherToday.scaleX = 0.7; |
80 |
_weatherToday.scaleY = 0.7; |
81 |
break; |
82 |
|
83 |
case "27": |
84 |
case "29": |
85 |
var weather09:weather09 = new weather09(); |
86 |
_weatherToday.addChild(weather09); |
87 |
_weatherToday.scaleX = 0.7; |
88 |
_weatherToday.scaleY = 0.7; |
89 |
break; |
90 |
|
91 |
case "5": |
92 |
case "6": |
93 |
case "7": |
94 |
case "35": |
95 |
var weather10:weather10 = new weather10(); |
96 |
_weatherToday.addChild(weather10); |
97 |
_weatherToday.scaleX = 0.7; |
98 |
_weatherToday.scaleY = 0.7; |
99 |
break; |
100 |
|
101 |
case "8": |
102 |
case "10": |
103 |
case "13": |
104 |
case "14": |
105 |
case "15": |
106 |
case "16": |
107 |
case "17": |
108 |
case "18": |
109 |
var weather11:weather11 = new weather11(); |
110 |
_weatherToday.addChild(weather11); |
111 |
_weatherToday.scaleX = 0.7; |
112 |
_weatherToday.scaleY = 0.7; |
113 |
break; |
114 |
|
115 |
case "9": |
116 |
case "11": |
117 |
case "12": |
118 |
var weather12:weather12 = new weather012(); |
119 |
_weatherToday.addChild(weather12); |
120 |
_weatherToday.scaleX = 0.7; |
121 |
_weatherToday.scaleY = 0.7; |
122 |
break; |
123 |
|
124 |
|
125 |
case "40": |
126 |
var weather13:weather13 = new weather13(); |
127 |
_weatherToday.addChild(weather13); |
128 |
_weatherToday.scaleX = 0.7; |
129 |
_weatherToday.scaleY = 0.7; |
130 |
break; |
131 |
}
|
In this case I just used 13 icons but you can use more if you want, or fewer, that's up to you. Just remember, Yahoo uses 40 codes, so you have to assign them all to an icon. You can see a list of the meanings of all the codes at developer.yahoo.com.
Step 13: Add a Flip Effect
Well, we've covered the hard part; now let's make it look nice. If we want to add more information or change the location we will need more space, so we'll put all that we have created into one movie clip. To do that, just select it all, press F8 (to convert it to a symbol) and export your new symbol for ActionScript, with a class name of Front. Then erase it from the stage, create the background, and convert this to a movie clip and export it for ActionScript too, with a class name of Back.


Now let's call them from our ActionScript file:
1 |
private var _front:Front; |
2 |
private var _back:Back; |
3 |
|
4 |
//all below code goes in Weather() constructor
|
5 |
|
6 |
_front = new Front(); |
7 |
this.addChild(_front); |
8 |
_front.y = 100; |
9 |
_front.x = 160; |
10 |
_font.rotationY = 0; |
11 |
_front.btn.buttonMode = true; |
12 |
_front.btn.addEventListener(MouseEvent.CLICK, turnAround); |
13 |
_front.addChild(_weatherToday); |
14 |
|
15 |
//this is going to be behind so we don't want it to be visible yet, and we need to set the rotation to -180
|
16 |
_back = new Back(); |
17 |
_back.y = 100; |
18 |
_back.x = 160; |
19 |
_back.back.buttonMode = true; |
20 |
_back.back.addEventListener(MouseEvent.CLICK, turnAround); |
21 |
_back.rotationY = -180; |
22 |
_back.visible = false; |
23 |
this.addChild(_back); |
Step 14: Set Up the Tween
We have our movie clip, so now we need to make it flip. To do that we are going to use the Tweener library which you can find at http://code.google.com/p/tweener/. Download it, and extract it so that the \caurina\ folder is in the same folder as your FLA.
For this project we are going to use just one function from it: we'll make it flip using the turnAround() function to look cool. Put the following code in the appropriate places in your document class:
1 |
import caurina.transitions.Tweener; |
2 |
|
3 |
private var _currentFace:String; |
4 |
|
5 |
//flip the faces and then calls the function that change the order of the faces and finish the animation
|
6 |
private function turnAround(event:MouseEvent):void { |
7 |
Tweener.addTween(_back, { rotationY: -90, onComplete:changeIndex, time:0.5, transition:"linear" } ); |
8 |
Tweener.addTween(_back, { scaleY:0.6, scaleX:0.6, time:0.3, transition:"linear" } ); |
9 |
Tweener.addTween(_front, { scaleY:0.6, scaleX:0.6, time:0.3, transition:"linear" } ); |
10 |
Tweener.addTween(_front, { rotationY:90, time:0.5, transition:"linear" } ); |
11 |
}
|
12 |
|
13 |
//we use a String, _currentFace, so it can know which face is in front
|
14 |
private function changeIndex():void { |
15 |
if (_currentFace == "front") { |
16 |
this.setChildIndex(_front, 0); |
17 |
Tweener.addTween(_back, { rotationY: 0, time:0.5, transition:"linear" } ); |
18 |
Tweener.addTween(_back, { scaleY:1, scaleX:1, time:0.6, transition:"linear" } ); |
19 |
Tweener.addTween(_front, { rotationY:180, time:0.5, transition:"linear" } ); |
20 |
Tweener.addTween(_front, { scaleY:1, scaleX:1, time:0.6, transition:"linear" } ); |
21 |
_currentFace = "back"; |
22 |
_front.visible = false; |
23 |
_back.visible = true; |
24 |
} else { |
25 |
this.setChildIndex(_back, 0); |
26 |
Tweener.addTween(_back, { rotationY: -180, time:0.5, transition:"linear" } ); |
27 |
Tweener.addTween(_back, { scaleY:1, scaleX:1, time:0.6, transition:"linear" } ); |
28 |
Tweener.addTween(_front, { rotationY:0, time:0.5, transition:"linear" } ); |
29 |
Tweener.addTween(_front, { scaleY:1, scaleX:1, time:0.6, transition:"linear" } ); |
30 |
_currentFace = "front"; |
31 |
_front.visible = true; |
32 |
_back.visible = false; |
33 |
}
|
34 |
}
|
Step 15: Add Locations
Now that we have more space in the back we can add more states or info or whatever you want. Briefly, I'll add more locations. What we need to do is to go to Flash and press Ctrl+F7 (Windows) or Command+F7 (Mac) to reveal the Components panel. Drag the Combo Box to your Library, then add this to your document class:
1 |
import flash.xml.*; |
2 |
|
3 |
_comboBox = new ComboBox(); |
4 |
|
5 |
//inside the constructor
|
6 |
//the default text
|
7 |
_comboBox.prompt = "Choose your location:"; |
8 |
//repeat this for each location that you want to add
|
9 |
//remember to get the location's URL from the Yahoo site
|
10 |
comboBox.addItem( { Location:"Mahtomedi", url: "http://weather.yahooapis.com/forecastrss?w=2444293&u=c"} ); |
11 |
//calls the function that give the value to the ComboBox
|
12 |
_comboBox.labelFunction = nameLabelFunction; |
13 |
_comboBox.width = 150; |
14 |
_comboBox.editable = false; |
15 |
//calls the function that is going to change the data
|
16 |
_comboBox.addEventListener(Event.CHANGE, changeLocation); |
17 |
|
18 |
|
19 |
private function nameLabelFunction(item:Object):String { |
20 |
var str:String; |
21 |
if (item == null) { |
22 |
str = _comboBox.value; |
23 |
} else { |
24 |
str = item.Location ; |
25 |
}
|
26 |
return str; |
27 |
}
|
28 |
|
29 |
//reaload the data and reassign the data of your application
|
30 |
private function changeProvince(event:Event):void { |
31 |
loadXML(_comboBox.selectedItem.url); |
32 |
}
|
Step 16: Enjoy!
Now enjoy your application, add fancy stuff and credits (don't forget Yahoo!)
Conclusion
Now we have our weather application I hope you learned a lot, if you have any questions just leave a comment.
I hope you liked this tutorial, thanks for reading!