1

I'm working with Flex 10 for web applications.

I need to save a binary file which is received in Flex from a web service. To do this I need to use FileReference.save(), which must be invoked by a user event (mouse or keyboard) for security requirements of Flex. The general idea is as follows:

protected function cmdSave(event:MouseEvent):void{

    var inp:String = webService.getString("fieldBinary"); //here I get the data
    var base64Dec:Base64Decoder = new Base64Decoder();
    base64Dec.decode(inp);
    var byteArray:ByteArray = base64Dec.toByteArray();

    var fileRef:FileReference = new FileReference();
    fileRef.save(byteArray, "output.pdf");
}

Now my problem is that the method to consume a web service is synchronous. Therefore, my original function should split in two, and the call to FileReference.save() is not performed in the function triggered by the user event, but in the function triggered by de web service, something like:

protected function cmdSave(event:MouseEvent):void{

    responseFunction=cmdSave_End;
    methodToCallWebService(responseFunction);
}

protected function cmdSave_End(event:Ws_Event):void{

    var webService = Ws_event.getResult();
    var inp:String = webService.getString("fieldBinary"); //here I get the data
    var base64Dec:Base64Decoder = new Base64Decoder();
    base64Dec.decode(inp);
    var byteArray:ByteArray = base64Dec.toByteArray();

    var fileRef:FileReference = new FileReference();
    fileRef.save(byteArray, "output.pdf");
}

(I omit most of the code)

At this time, FileReference throws this error:

Error #2176: Certain actions, such as those that display a pop-up window, may only be invoked upon user interaction, for example by a mouse click or button press.

Would anyone think a way to fix this? I need FileReference run in the function invoked by the user.

Thanks in advance.

ketan
  • 19,129
  • 42
  • 60
  • 98
Rodrigo
  • 567
  • 7
  • 24
  • 1
    You can not use `fileref.save()` directly. you should call that on any event like click event. So for that can do like. Save bytearray in some public variable and put one button and on button click call `fileref.save(byteArray, "output.pdf")`. – ketan Feb 28 '15 at 04:02

1 Answers1

1

You can trick this by forcing the user to click some button and save on disk only at that point.

What I did was to show an Alert message telling the user that the file has been successfully generated, and on the alert handle function call the save method.

private var _byteArray:ByteArray;

protected function cmdSave(event:MouseEvent):void
{
    responseFunction=cmdSave_End;
    methodToCallWebService(responseFunction);
}

protected function cmdSave_End(event:Ws_Event):void{

    var webService = Ws_event.getResult();
    var inp:String = webService.getString("fieldBinary"); //here I get the data
    var base64Dec:Base64Decoder = new Base64Decoder();
    base64Dec.decode(inp);
    _byteArray = base64Dec.toByteArray();

    Alert.show("File content was generated", "Info",   Alert.OK, this, alertClickHandler);

}


// Event handler function for Alert
private function alertClickHandler(evt:CloseEvent):void 
{
    var fileRef:FileReference = new FileReference();
    fileRef.save(_byteArray, "output.pdf");
}
Adrian Pirvulescu
  • 4,308
  • 3
  • 30
  • 47
  • I initially disliked your answer by uncomfortable. Following your idea, I tried to make a blind loop waiting that the global variable is loaded in another function, to continue with FileReference.save() in the initial function, but it did not work. Therefore, I used your suggestion and it worked as expected. Thank you very much for your help. – Rodrigo Feb 28 '15 at 15:40
  • 1
    You are welcome. The problem with the loop is that your "function" where the fr.save() method is must be an handler for an "user-interaction" event (like click). What I do not understand from your approach is why do you manually create a bytearray on the client side when you already need to DOWNLOAD it. Usually FileRefference.save() is used when file content is generated on client. INSTEAD you could use FileReference.download() and not the WebService call... http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/FileReference.html#download() – Adrian Pirvulescu Feb 28 '15 at 19:45
  • We have documents stored in a sql table as binary data. The java webservice obtain the varbinary data from a stored procedure, as byte[ ] and builds an xml in which data is encoded in a base64 string. I load the bitmaps directly into an , but other documents must rebuild and save on the client pc with FileReference. – Rodrigo Feb 28 '15 at 22:23
  • Ok, it makes sense, I just saw you were saving in your sample just a "output.pdf" :) – Adrian Pirvulescu Feb 28 '15 at 23:11