Thursday, November 15, 2007

I am updating my blog after a long time, thanks to my busy schedule but now I am back. During these days I was engaged with a usability project as well as a flex project.

In my Flex application I came across a very challenging scenario. Here is a background of what we were doing. We had our main application made up of various nested flex applications. Finally all the smaller applications were getting loaded into the main application using SwfLoader component of Flex. Everything was looking good till the time our dear client did something which they love to do -change the requirements. To meet their requirement it was necessary to pass a lot of arguments from the main application to the smaller nested applications. Now it looked pretty simple approach.



I did some Google search but could not get any help. Finally I got a simple example in Flex 2 Developers’ Guide which is the documentation on Flex 2 provided by Adobe to help poor developers like me.


Flex 2 Developers’ Guide has an example of passing arguments around various applications on page 276. It gives a brief idea of argument passing between applications however one has to alter the code to make it usable.
To enable argument passing you need to use SystemManager class provided in the Flex 2 frame work. Here is the code snippet


[Bindable]
public var loadedSM:SystemManager;
// Initialize variable with information from the loaded application.
private function initNestedAppProps():void
{
loadedSM = SystemManager(myLoader.content);
}

In the above code ‘myLoader’ is the SwfLoader component used to load a swf file or an application. You can define it like this

<mx:swfloader id="myLoader" source="local.swf" width="300" creationcomplete="initNestedAppProps();">


Lets say you want to change a public variable ‘varOne’ of local.swf which is loaded using SwfLoader, we write the following function:

public function updateNestedLabels():void {
loadedSM.application["varOne"] = "I was just updated";
}

To call this function we need to modify the initNestedAppProps() function to the following
private function initNestedAppProps():void
{
loadedSM = SystemManager(myLoader.content);
l
oadedSM.addEventListener(FlexEvent.APPLICATION_COMPLETE,updateNestedLabels);
updateNestedLabels();
}
The second line of initNestedAppProps() is most important as it assigns an event listener to SystemManager when the application is loaded completely. If this code is missing you will be slapped with a ‘Null Object Reference Error’ which took me 2 days to resolve.

In this way arguments can be passed across various nested applications in flex 2 using swfLoader.



13 comments:

Chris Blown said...

Thanks, always wondered about that.

Anonymous said...

Thanks for the advice. I spent many hours on the same problem. I still have a little problem: it will sometimes work and sometimes return null. Is there any other event that is dispatched later that I can listen for?

Rahul Mainkar said...

Hi Anna,
As far as I know this is the best way to handle swfloader events.
Are you getting some kind of errors using this approach?

Anonymous said...

that was of great help..
but could you please complete the following line..i am unable to see the complete line.

and what should we write in the listener function

i am struggling with null reference still


loadedSM.addEventListener(FlexEvent.APPLICATION_COMPLETE,upda

Anonymous said...

that was of great help..
but could you please complete the following line..i am unable to see the complete line.

and what should we write in the listener function
loadedSM.addEventListener(FlexEvent.APPLICATION_COMPLETE,????)

i am struggling with null reference still

Rahul Mainkar said...

Chandana,
Here is the complete line. I wonder why you were not able to see the complete line
loadedSM.addEventListener(FlexEvent.APPLICATION_COMPLETE,updateNestedLabels);

Rahul Mainkar said...

Chandana,
Here is the complete line. I wonder why you were not able to see the complete line
loadedSM.addEventListener(FlexEvent.APPLICATION_COMPLETE,updateNestedLabels);

Anonymous said...

What comes after "APPLICATION_CO"?

TIA

Anonymous said...

Ahhh... if you use Internet Exploder you can read the whole line: (FlexEvent. APPLICATION_COMPLETE, updateNestedLabels);

afriyie said...

With Flex 3.0 this only worked for me as I used the >>complete<< event with the SWFLoader instead of the >>creationcomplete<< event. Otherwise I got a null object error.

savage said...

Awesome Post! I was struggling with this few a couple of hours. Also confirmed in Flex 3.2 that "swfLoader.addEventListener(Event.COMPLETE" is needed, FlexEvent.CREATION_COMPLETE does not work. Thanks!

Rouslan said...

Does anyone know how to do this the other way round? Meaning upstream. Say, if you wanted to pass arguments from the loaded content to the loader. I ran into a problem where I load flash swf files into Flex (running in the browser) and there is absolutely no way to access functions, only ways to set simple variables. Very frustrating as it seems to be undocumented. Also, sandboxBridge won't work since it's AIR only. Any pointers would be appreciated and if you're in NYC, I'll buy you a couple-a-beers!

Rouslan

Tenth Planet Technology said...

dont say that ur a poor developer