
Time for action - visualizing the info
Enough traces! It's time we displayed something in our actual SWF.
CustomGraphContainerController
inherits a method called renderGraphObject()
which will take care of this for us. All we have to do is pass it an argument of type graph.GraphObject
.
GraphObject.as
is a simple class; feel free to open it and take a look:
package graph { import graph.controls.GraphObjectRenderer; public dynamic class GraphObject extends BaseGraphItem { public var rendererObject:GraphObjectRenderer; public var graphObjectListRenderers:Array = []; public function GraphObject() { } } }
Honestly, there's no need to worry about any of the code there. All you need to know is that it's dynamic
, which means that we can assign new properties to it during runtime, without having to specify their names beforehand. So we can do this:
var graphObject:GraphObject = new GraphObject(); graphObject.favoriteColor = "red";
When a GraphObject
is passed to the CustomGraphContainerController.renderGraphObject()
method, every single property of the GraphObject
will be rendered in a fancy list, automatically. Every single property apart from the two that are defined in the class already, that is!
So what we have to do, inside CustomGraphContainerController.onGraphDataLoadComplete()
, is:
- Create a new instance of
GraphObject
. - Copy all the properties of
decodedJSON
to this newGraphObject
. - Pass the
GraphObject
torenderGraphObject()
. - The code for doing that is as follows:
private function onGraphDataLoadComplete(a_event:Event):void { var loader:URLLoader = a_event.target as URLLoader; //obtain whatever data was loaded, and trace it var graphData:String = loader.data; var decodedJSON:Object = JSON.decode(graphData); var graphObject:GraphObject = new GraphObject(); //copy all the properties from decodedJSON to graphObject for (var key:String in decodedJSON) { graphObject[key] = decodedJSON[key]; } this.renderGraphObject(graphObject); }
- Compile and test. The SWF is shown in the next screenshot:
You can click the Zoom In button a few times to make the Renderer larger and clearer, as in the screenshot above. Your Renderer might display the fields in a different order than depicted; Facebook returns the fields in an arbitrary order.
What just happened?
The window that appeared on stage is what I call a Renderer—specifically, a Graph Object Renderer. It can be dragged around by the title bar, the contents can be scrolled, and you can close it by clicking the button in the top-right corner.
So, you've successfully fetched data from Facebook's Graph API and displayed it in a SWF. Your SWF is flexible; change request.url
to point to the Graph URL of a different Facebook object and you'll see it displayed in the Renderer.
Most of the data from the GraphObject
is displayed in a text area inside the window, in a simple "key: value
" format. The Page's name
field is displayed in the window's title bar, and if the Page has a picture
field (we can see from the JSON that PacktPub
does), the image is downloaded and displayed inside the renderer using a Loader
.
Note
Like URLLoader
, the flash.display.Loader
class downloads the object that a given URLRequest
points to, dispatching a COMPLETE
event when ready. Unlike URLLoader
, Loader is used to download images and SWFs, and the event is actually dispatched by one of its sub-objects, contentLoaderInfo
. Also, Loader
extends DisplayObject
, and takes the appearance of the image when it has finished downloading.
Flash's security model prevents an image's data being accessed by SWFs residing on a different domain than the image itself, unless there is a cross-domain policy file on the domain of the image that allows it. Fortunately, Facebook's cross-domain policy file is lenient, allowing such access by every domain.
So, really, this is just a graphical way of representing a Page object from the Graph API.