Using FlashVars when loading a Flex app into another SWF
Posted on Monday, May 19, 2008 @ 15:47 CET
Back story
At work sometimes we create offline versions of the stuff we produce that run from a CD. To do this I normally create a wrapper SWF that loads in the main app SWF and everything is good to go. When its online we set FlashVars in the HTML page holding it using SWFObject's addVariable() method. To recreate this within the wrapper SWF I simpy populate _root with the same variables and then load in the app SWF into a MovieClip. This is a Flash 8 project (AS2) mind you, so the wrapper FLA looks like this:
_root.canHazCheese = "true";
_root.amountOfCheese = 1;
_root.flavour = "mozarella";
var loader:MovieClip = createEmptyMovieClip("loader", getNextHighestDepth());
loader.loadMovie("content/app.swf");
Then within the SWF that gets loaded in you access the FlashVars using _root.canHazCheese for example and you're done. The reason for using a wrapper SWF is that I can then easily publish it as a standalone projector from within the Flash IDE which is good enough for our purposes.
The problem
What if the app is built in Flex? Well, in AS3 you no longer have _root, and the FlashVars have moved. In Flash they're in root.loaderInfo.parameters and in Flex they're in Application.application.parameters. So now you have to find a way of adding these vars to the parameters object.
At first to avoid this I tried simply sending them in as query string parameters to the SWF, for example loading in app.swf?canHazCheese=true&amountOfCheese=1&flavour=mozarella, and this works fine when the SWF is loaded over http://. However, since this is going to run of a CD everything is loaded over file:// and the query string method doesn't work because along the way someone gets confused and thinks that the query string is part of the filename, and therefore doesn't find the file.
The solution
While testing various things in Flash (with an AS3 wrapper SWF) I found that when you load in a Flex SWF using the Loader class, the Event.INIT handler was tracing out the loader.content as an mx.managers.SystemManager object. Checking the LiveDocs I found that the document property was a reference to the document object, but loader.content.document traced out as null.
So what to do? Wait a frame of course :) So in the Event.INIT handler we set up an ENTER_FRAME handler that runs until the document property is defined, and then populate the document.parameters with the FlashVars. Phew! Anyways, check the code below:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.INIT, onLoaded);
loader.load(new URLRequest("flex-app.swf"));
addChild(loader);
function onLoaded(event:Event=null):void {
var flexSWF:MovieClip = event.target.content as MovieClip;
flexSWF.addEventListener(Event.ENTER_FRAME, checkContents);
}
function checkContents(event:Event):void {
var mc:MovieClip = event.target as MovieClip;
if(mc.document) {
mc.removeEventListener(Event.ENTER_FRAME, checkContents);
mc.document.parameters.canHazCheese = "true";
mc.document.parameters.amountOfCheese = 1;
mc.document.parameters.flavour = "mozarella";
}
}
stop();
As you know, Event.INIT fires when the SWF has been loaded in and initialized. In any case, once this is done the Flex app starts initializing and you have to wait until the application dispatches FlexEvent.APPLICATION_COMPLETE, and because we're in Flash we can't use Flex classes without mucking about with SWCs, so once again waiting a frame saves the day! :)
Note: I found that using mc.application in checkContents() works as well, but since the docs state that application is read-only I decided to use mc.document instead.
- paulo


Comments:
Thanks for the info...quick question:
What if you wanted to send parameters to a SWF that has been loaded in Flex with SWFLoader?
And the SWF is not another Flex app, but a AS3 Flash SWF.
Seems that there is no real way to send flashvars to a SWF from Flex, or is there?
Thanks a million!
Dan
# March 19, 2009 00:02 CET
Hi Daniel, if its online you can just append the FlashVars to the URL using the query string, for example:
<mx:SWFLoader source="movie.swf?myVar=yoyoyo" />
# March 19, 2009 13:13 CET
As soon as I try to load a SWF created with Flex in Flash CS3 using a Loader instance, I get the following error:
TypeError: Error #1034: Type Coercion failed: cannot convert xxx@40cd4d01 to mx.core.IUIComponent. at mx.managers::SystemManager/initializeTopLevelWindow()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3188] at mx.managers::SystemManager/http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3064] at mx.managers::SystemManager/docFrameListener()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2916]
Do you have any idea how I can resolve this, in order to use SWFs created with Flex in a Flash CS3 project? Or isn't this possible at all?
# April 07, 2009 14:31 CET
Hi Tom, I'm not sure why you're getting that problem. I followed these steps again with different projects and it worked.
Are you using RSL's? As far as I can tell if the Flex project publishes a self-contained SWF it seems to be OK.
# April 14, 2009 09:02 CET
Hi Paulo, thx for your reply.
I got it working last week. My mistake was that I did the addChild on the loader before the loading was completed. This seems to be crucial when dealing with Flex SWFs.
This article and example brought me on the right track: http://algorithmist.wordpress.com/2008/04/30/load-flex-into-flash/
Best, Tom
# April 14, 2009 22:47 CET
Thanks a lot, this was very helpful. It's sad that we have to use the enter frame event though.
# June 05, 2009 21:41 CET
One thing I found useful, to avoid having the loaded flex SWF eat all of the interactive events (mouse click/move) and prevent my Flash controls from functioning, was to set a mask on the flex application. This sufficiently boxed in the flex app so I did not have to worry about interference with other controls on the Flash stage.
# July 28, 2009 00:32 CET
Post a comment:
You must have Flash and JavaScript enabled to post a comment.