
Time for action - rendering Lists of Posts
Since a Graph List's data
property is an array of Graph Objects, we could just loop through the array and create a new Graph Object Renderer for each element. Feel free to have a go at this, if you like, but I've got another solution.
I've created a second renderer: this time, a Graph List Renderer. I've also created a class graph.GraphList
. And CustomGraphContainerController
inherits a method called renderGraphList()
. Perhaps unsurprisingly, this takes an object of type graph.GraphList
as a parameter, and creates a new Graph List Renderer to display its contents. So, we need to take a Graph List that we receive from the Graph API, and turn it into an instance of the GraphList
class. The GraphList
class is a little more sophisticated than the GraphObject
class; it has a method called addToList()
, to which we can pass any GraphObject
instance to be added to the list.
We'll still loop through the data
array, then, but instead of rendering each GraphObject
on its own, we'll add each one to a GraphList
and render that.
Modify the URL that CustomGraphContainerController
requests, so that it loads the list of posts:
public function CustomGraphContainerController (a_graphControlContainer:GraphControlContainer) { super(a_graphControlContainer); var loader:URLLoader = new URLLoader(); var request:URLRequest = new URLRequest(); //Specify which Graph URL to load request.url = "https://graph.facebook.com/PacktPub/posts"; loader.addEventListener(Event.COMPLETE, onGraphDataLoadComplete); //Start the actual loading process loader.load(request); }
Now, once this is loaded, we need to check whether the item returned is a Graph Object or a Graph List. We can do this by looking for a property called data
; if one exists, we'll assume it's a List.
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);
if (decodedJSON.data) { //has a "data" property so we assume it is a Graph List } else { //no "data" so we assume it is a Graph Object
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);
}
}
Inside this if
block, we first create a new GraphList
instance:
if (decodedJSON.data)
{
//has a "data" property so we assume it is a Graph List
var graphList:GraphList = new GraphList();
}
(You will need to import graph.GraphList.)
Next, remember than decodedJSON.data
is an array of objects; we loop through this array, and create a GraphObject
from each element.
if (decodedJSON.data) { //has a "data" property so we assume it is a Graph List var graphList:GraphList = new GraphList(); var childGraphObject:GraphObject; for each (var childObject:Object in decodedJSON.data) { childGraphObject = new GraphObject(); for (var childKey:String in childObject) { childGraphObject[childKey] = childObject[childKey]; } } }
This is basically the same thing we did with the decodedJSON
when loading a single Graph Object.
What about the other property inside the Graph List, the paging
object? We should add that too:
if (decodedJSON.data)
{
//has a "data" property so we assume it is a Graph List
var graphList:GraphList = new GraphList();
var childGraphObject:GraphObject;
for each (var childObject:Object in decodedJSON.data)
{
childGraphObject = new GraphObject();
for (var childKey:String in childObject)
{
childGraphObject[childKey] = childObject[childKey];
}
graphList.addToList(childGraphObject);
}
graphList.paging = decodedJSON.paging;
}
Finally, we pass the GraphList
instance to renderGraphList():
if (decodedJSON.data)
{
//has a "data" property so we assume it is a Graph List
var graphList:GraphList = new GraphList();
var childGraphObject:GraphObject;
for each (var childObject:Object in decodedJSON.data)
{
childGraphObject = new GraphObject();
for (var childKey:String in childObject)
{
childGraphObject[childKey] = childObject[childKey];
}
graphList.addToList(childGraphObject);
}
graphList.paging = decodedJSON.paging;
this.renderGraphList(graphList);
}
Compile the SWF and test it. The following screenshot shows the result:

It's a scrollable window containing all the Graph Objects from the list.
What happens when you click the Pop Out button underneath a Graph Object?

What just happened?
The Graph Object pops out into its own Graph Object Renderer, with a gray line connecting it to the list to which it belongs. This lets you look at several children of a list at the same time:

(You can drag the individual renderers to reposition them, or drag the background to move everything at once.)
This makes it clear that a Graph List is just a collection of Graph Objects.