Tuesday, October 09, 2007

Interacting with Flex in Flash

I was trying to bring a Flex 2 SWF into Flash CS3 and interact with it. I was able to load the Flex swf without a problem but when I tried to access a public property or function I'd get the following error:

ReferenceError: Error #1069: Property hello not found on
_Main_mx_managers_SystemManager and there is no default value.

So I did the natural thing and Googled it before spending time figuring it out :)
Unfortunately, my search came up empty :(

Looking into the docs class mx.managers.SystemManager gave me the clue I needed. To get at the actual application, I needed to get to the first child of the loaded content. The compiler was unhappy with calling getChildAt() on the content object, so I cast it into an Object along the lines:

var flexApp:Object = (loader.content as Object).getChildAt(0);
trace(flexApp.hello);

That did the trick!

7 comments:

  1. I'm having a problem with this. I need to be able to interact with a Flex 3 app inside a Flash 9 swf. I came onto the same solution as you, but it doesn't work for me.

    I always got an index out of bounds with 'flexApp.getChildAt(0)'. When tracing the numChildren, it gave me -1 as result.

    Tried other solutions, like using a LocalConnection, but that doesn't seem to work properly either, and seeing as we need a lot more sending and receiving than the max 40KB LocalConnection is capable of, that solution is not workable.

    Have you encountered the numChildren = -1 problem before?

    ReplyDelete
  2. Tom, I am working with Flex 2 (I should make that clear in the blog posting). I am not working with Flex 3 yet, so I'm not sure if the APIs changed, thus breaking my example.

    ReplyDelete
  3. Tom, make sure that the Flex SWF is being loaded. My code snippet assumes that you created a Loader object and called load() before accessing the content property of it.

    ReplyDelete
  4. I was doing that, but indeed the Flex SWF wasn't completely loaded yet, even though the INIT event was dispatched. So I had the Flex app communicate with the Flash app first, to let the Flash app know that Flex was fully initialized, and that seemed to do the trick :)

    Now to get code hinting working ;)

    ReplyDelete
  5. Ah! Don't use the INIT event use COMPLETE. And speaking of "complete", here is my complete example:

    package {
    import flash.display.DisplayObjectContainer;
    import flash.display.Loader;
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.net.URLRequest;
    import flash.events.*;

    public class FlexInFlash extends MovieClip{
    public var loader:Loader = new Loader();

    public function FlexInFlash() {
    var request:URLRequest = new URLRequest("testt.swf");
    loader.load(request);
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
    addChild(loader);
    buttonInFlash.addEventListener(MouseEvent.CLICK, onClick);
    }
    public function onComplete(e:Event):void {
    trace("onComplete");
    addChildAt(loader, 0);
    }
    public function onClick(e:MouseEvent):void{
    var fromFlex:Object = (loader.content as Object).getChildAt(0);
    trace(fromFlex.hello);
    }

    }

    }

    ReplyDelete
  6. Just wanted to add to the conversation here. I tried your latest code that you had posted in December of '07, John, and was initially having problems. Everything looked like it should be working, though.

    The solution was actually to wait a couple of seconds before trying to start utilizing the flex component I was importing. Even though the swf load complete event had fired off, the flex component still needed a certain amount of time to initialize. With the delay, everything was able to initialize and I could make calls out of the component, etc.

    Hopefully this might help someone else who stumbles on this blog.

    ReplyDelete
  7. Andrew, the code I posted is functioning code, but there are a couple givens... The code is based on Flex 2 and Flash 9, you shouldn't try to interact with it before the COMPLETE event, and this assumes that the swf is not in turn loading additional assets.

    ReplyDelete