web-servicesactionscript-3apache-flexfilereference

Save in flex a file get by web service


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.


Solution

  • 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");
    }