views:

51

answers:

1

Is there a way how to check if UPLOAD_COMPLETE_DATA event was not dispatched after COMPLETE in Flash?

I'm working on file uploader. It uploads file after file – after COMPLETE next file starts uploading – this is repeated for every file. On last file on COMPLETE if there is no next file allCompleteHandler is dispatched and if some errors occurs it shows that errors at once trough javascript to the user.

I handle that errors in javascript – it stores every error to variable in javascript and after all completed it shows that errors.

The problem is:
I can't store error from the last file (error from server that I get through UPLOAD_COMPLETE_DATA) because this is dispatched after COMPLETE (after allCompleteHandler).

I need to solve this because I don't wont to show javascript alert box for every invalid file (if there are 100 files for example).

var parameters:Object = LoaderInfo(this.root.loaderInfo).parameters,

    fileFilter:Array,
    browseFilter:Array = [],

    files:FileReferenceList = new FileReferenceList(),
    selectedFiles:Array = [],
    file:FileReference = new FileReference(),

    url:URLRequest = new URLRequest(parameters.phpScript),
    uploadFolder,

    postMaxSize:Number,
    uploadMaxFilesize:Number,
    maxInputTime:int,

    speedTimer:Timer = new Timer(1000),
    uploadTimer:Timer = new Timer(60000, 1),

    count:int = 0,

    totalBytes:Number = 0,
    processedBytes:Number = 0,
    currentBytes:Number = 0,
    currentBytes2:Number = 0,
    lastBytes:Number = 0,
    uploadSpeed:Number = 0,

    inProgress:Boolean = false;

// Browse filter setup
fileFilter = ExternalInterface.call(parameters.fileManager + ".getFileFilter");

if (fileFilter) {
    for (var i:int = 0; i < fileFilter.length; i++) {
        browseFilter.push(new FileFilter(fileFilter[i][0], fileFilter[i][1]));
    }
}

function clickHandler(event:MouseEvent):void {
    if (!inProgress) {
        uploadFolder = ExternalInterface.call(parameters.fileManager + ".getCurrentFolder");

        if (uploadFolder != undefined) {
            files.browse(browseFilter);
        }
    }
}

stage.addEventListener(MouseEvent.CLICK, clickHandler);

function selectHandler(event:Event):void {
    var variables:URLVariables = new URLVariables();

    variables.folder = uploadFolder;
    url.data = variables;
    url.method = URLRequestMethod.POST;

    selectedFiles = files.fileList;

    postMaxSize = ExternalInterface.call(parameters.fileManager + ".getPostMaxSize");
    postMaxSize = postMaxSize ? postMaxSize : 50 * 1024 * 1024;

    uploadMaxFilesize = ExternalInterface.call(parameters.fileManager + ".getUploadMaxFilesize");
    uploadMaxFilesize = uploadMaxFilesize ? uploadMaxFilesize : 50 * 1024 * 1024;

    maxInputTime = ExternalInterface.call(parameters.fileManager + ".getMaxInputTime");
    maxInputTime = maxInputTime ? maxInputTime : 60;

    // Get total size of selected files
    for (var i:int = 0; i < selectedFiles.length; i++) {
        totalBytes += selectedFiles[i].size;
    }

    ExternalInterface.call(parameters.fileManager + ".selectHandler", {
        selectedFiles : selectedFiles,
        totalBytes    : totalBytes
    });

    // Start upload process
    inProgress = true;
    speedTimer.start();
    upload();
}

files.addEventListener(Event.SELECT, selectHandler);

function upload():void {
    uploadTimer.reset();

    currentBytes2 = 0;

    if (count) {
        processedBytes += file.size;

        if (currentBytes < processedBytes) {
            currentBytes = processedBytes;
        }
    }

    if (selectedFiles.length) {
        file = FileReference(selectedFiles.shift());
        count++;

        ExternalInterface.call(parameters.fileManager + ".beforeUploadHandler", {
            file         : file,
            currentBytes : currentBytes
        });

        if (file.size <= postMaxSize) {
            if (file.size <= uploadMaxFilesize) {
                file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
                file.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
                file.addEventListener(Event.OPEN, openHandler);
                file.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
                file.addEventListener(ProgressEvent.PROGRESS, progressHandler);
                file.addEventListener(Event.COMPLETE, completeHandler);
                file.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, uploadCompleteDataHandler);

                file.upload(url);
            } else {
                ExternalInterface.call(parameters.fileManager + ".uploadMaxFilesizeHandler", file);
                upload();
            }
        } else {
            ExternalInterface.call(parameters.fileManager + ".postMaxSizeHandler", file);
            upload();
        }
    } else {
        ExternalInterface.call(parameters.fileManager + ".allCompleteHandler", {
            currentBytes : currentBytes
        });

        speedTimer.stop();

        count = 0;

        totalBytes = 0;
        processedBytes = 0;
        currentBytes = 0;
        lastBytes = 0;
        uploadSpeed = 0;

        inProgress = false;
    }
}

function securityErrorHandler(event:SecurityErrorEvent):void {
    ExternalInterface.call(parameters.fileManager + ".securityErrorHandler", event);
}

function httpStatusHandler(event:HTTPStatusEvent):void {
    ExternalInterface.call(parameters.fileManager + ".httpStatusHandler", event);
    selectedFiles = [];
}

function openHandler(event:Event):void {
    ExternalInterface.call(parameters.fileManager + ".openHandler", event);

    uploadTimer.delay = maxInputTime * 1000;
    uploadTimer.start();
}

function ioErrorHandler(event:IOErrorEvent):void {
    ExternalInterface.call(parameters.fileManager + ".ioErrorHandler", event);
    upload();
}

function progressHandler(event:ProgressEvent):void {
    currentBytes += event.bytesLoaded - currentBytes2;
    currentBytes2 = event.bytesLoaded;

    ExternalInterface.call(parameters.fileManager + ".progressHandler", {
        current      : event,
        currentBytes : currentBytes
    });
}

function completeHandler(event:Event):void {
    ExternalInterface.call(parameters.fileManager + ".completeHandler", event);
    upload();
}

function uploadCompleteDataHandler(event:DataEvent):void {
    ExternalInterface.call(parameters.fileManager + ".uploadCompleteDataHandler", "(" + event.data + ")");
}

function updateUploadSpeed(event:TimerEvent):void {
    if (currentBytes > lastBytes) {
        uploadSpeed = currentBytes - lastBytes;

        ExternalInterface.call(parameters.fileManager + ".uploadSpeedHandler", uploadSpeed);

        lastBytes = currentBytes;
    }
}

speedTimer.addEventListener(TimerEvent.TIMER, updateUploadSpeed);

function maxInputTimeHandler(event:TimerEvent):void {
    ExternalInterface.call(parameters.fileManager + ".maxInputTimeHandler", file);
}

uploadTimer.addEventListener(TimerEvent.TIMER, maxInputTimeHandler);

function cancelUpload():void {
    file.cancel();

    selectedFiles = [];
    upload();
}

ExternalInterface.addCallback("cancelUpload", cancelUpload);

I can do this by setting up my PHP script to always return data and check this data and start next file upload with UPLOAD_COMPLETE_DATA, but I don't like this (it can be slow maybe I think)...

It is simple question but maybe hard to explain why I need that. Thank you for your help!

A: 

okay, what about http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/net/FileReference.html#event:progress

and sample

http://help.adobe.com/en_US/AS3LCR/Flash_10.0/flash/net/FileReference.html#includeExamplesSummary

http://blog.flexexamples.com/2007/10/30/using-for-the-filereference-classs-uploadcompletedata-event-to-capture-data-from-a-server-side-script/

http://bcdef.org/2006/12/09/new-event-for-as3-filereference-uploadcompletedata/

From the docs:

uploadCompleteData:

Dispatched after data is received from the server after a successful upload. This event is not dispatched if data is not returned from the server.

complete:

Dispatched when download is complete or when upload generates an HTTP status code of 200. For file download, this event is dispatched when Flash Player or Adobe AIR finishes downloading the entire file to disk. For file upload, this event is dispatched after the Flash Player or Adobe AIR receives an HTTP status code of 200 from the server receiving the transmission.

So, if you're uploading a file and not expecting any kind of response from the server you can just use complete. However, if you're expecting the server to return data to you in the upload's response then you need to wait for uploadCompleteData.

Eugene
I updated my question... I'm working on file uploader in Flash. What is result handler?
Jany
just updated...
Eugene
Yes, I have a working flash uploader... I also have configured all events and it works nice...I only need to chcek if `UPLOAD_COMPLETE_DATA` was not dispatched – maibe this is better question.
Jany
sorry, maybe this is stupid question, but where is your code of uploadin?
Eugene
Yes, exactly, I understand that... but I don't now if `UPLOAD_COMPLETE_DATA` will be dispatched or not... My aplication is uploading file after file (from user dialog box you can select many files) – `COMPLETE` event is dispatched always but `UPLOAD_COMPLETE_DATA` only if som error ocurs (only with some files that are invalid, etc.)
Jany
did you read my updated answer? the last part? your server is talking back the errors so uploadCompleteData dispatchs, if return is clear then Complete is dispatching.Yes?
Eugene
Yes :). I need to specify better my question so you will understand what I need :), but thanks.
Jany
It stores error for every file and after all files finished shows that errors. I check if all files was finished with `COMPLETE` – if `COMPLETE` was dispatched a next file starts uploading... After last file (on `COMPLETE`) it will shows that errors (if occured). But I can't store error on last file because `UPLOAD_COMPLETE_DATA` is dispatched after `COMPLETE`
Jany
0) you broke my brain1) why you say you can't say, why not just to save it to temporary variable2) why you need to store uploadCompleteData errors3) what is a problem btw complete and uploadCompleteData in serial dispatching?4) Jany, you should share your code, so I could help you a bit more))))
Eugene
I explained better my question and I pasted all my actionscript code, so I hope it helps to better understand what is my problem and why I need that...
Jany
very great that you already post your code, good. as for fast try to remove try/catch statement on upload function, i think it broke everything. I will review your code a bit later. thanks.
Eugene