It’s funny, actually, recently I was trying to remember which class was doing what I’m about to explain, and about the same time it happened.
If I had to choose, FileReference would be the strange fruit of the actionscript 3.0 classes. Only if I had to choose, though… I mean, I’m in a life or death situation, and my only way out is to choose which class is the strangest. In that case I would choose FileReference. Some might choose the Sound class, but me, yea, definitely FileReference…
Ok, so it goes like this: if you define FileReference inside the same function body that you call download()/upload() without declaring a nested function – it will fail. If you’re lucky, you’ll get an IO Error…
private function fail():void { var urlRequest:URLRequest = new URLRequest("http://www.lataco.com/taco_man.jpg"); var fileRef:FileReference = new FileReference(); fileRef.addEventListener(Event.COMPLETE, onComplete); fileRef.download(urlRequest); } private function onComplete(e:Event):void { trace("It's complete"); }
But, this works:
private function fail():void { var urlRequest:URLRequest = new URLRequest("http://www.lataco.com/taco_man.jpg"); var fileRef:FileReference = new FileReference(); fileRef.addEventListener(Event.COMPLETE, onComplete); fileRef.download(urlRequest); var succeed:Function = function(){}; } private function onComplete(e:Event):void { trace("It's complete"); }
Why? Beats me. I can only tell you how it works: If you’ve declared the FileReference in the same scope as the function calling upload()/download(), there needs to be a defined function declaration on the same scope for it to work.
I figure it has to do with referencing a location on your file system and garbage collection. Something about a nested function…
When it fails, sometimes it dispatches an IOErrorEvent, sometimes it does not. Not quite sure why.
HA! i love it….i feel the same way. I got stung on this one a while back. Then i had was doing a new project, and got stung again!- now i know….but when i saw this post, i had to laugh out loud. Thanks for sharing.
Thanks for the solution to a problem I struggled with far too long.
It’s pretty dumb that the second works, but it might be a timing issue. “fileRef” goes out of scope and gets garbage collected in the first example. The second example has fileRef trapped inside the new function’s closure, so it remains in scope for slightly longer, until the GC decides that *both* “fileRef” and “succeed” are out of scope, and cleans them both up. The safest option is to create a local member for fileRef.
I tried this and still got the issue. Any idea qhy?
Hi Mike,
Different Flex SDK/Flash IDE version and Flash Player version combinations can produce different results… Try creating a unit test for the process(es), or isolating the code in a clean project and debugging it with traces.
Try using callLater:
callLater(fileRef.download, new Array(urlRequest));