0
votes

We upload a document from SAPUI5 to our SAP System using the CREATE_STREAM Method of the oData Service in ABAP. The creation of the document works fine. What we would like to achieve is to get the response back to SAPUI5. Especially when there is an error during the creation of the document in the backend.

In Frontend we use the uploadSet Control.

...oUploadSet.uploadItem(oItem);

In the Backend we create a message with

...lo_message_container->add_message( iv_msg_type = /iwbep/cl_cos_logger=>error
iv_msg_number = '018'
iv_msg_id = lv_msg_id
iv_add_to_response_header = abap_true
)....

We can find the created message in the error protocol of our gateway server (/IWFND/ERROR_LOG). But how can this message be retrieved in SAPUI5 and used in the MessageManger Control?

We tried the onUploadCompleted Control but we can't find any response data there.

Can somebody explain how the response or a message header from the CREAT_STREAM method can be used in SAPUI5?

1
you could access the message by yourself, but if you are willing to use the message manager everything happens out of the box. help.sap.com/viewer/468a97775123488ab3345a0c48cadd8f/7.52.8/… - Benedikt Kromer
How can I access the message by myself? I did not manage to see it in onUploadCompleted. Or how can I make it all happen out of the box? The UploadSet is bound to a DocumentList Entityset. But a single Document item is bound to a UploadItemSet.... - Cruncher

1 Answers

1
votes

The "new" UploadSet control is kinda half-baked imo. The response will get lost in some internal method. This internal method will then trigger onUploadCompleted and you get nothing but useless information.

Lucky for us we can easily overwrite this internal stuff. UploadSet has an aggregation Uploader. We have to provide our own Uploader. Problem solved. Here is the line that needs to be modified.

sap.ui.define([
    "sap/m/upload/Uploader",
    ...
], function (Uploader, ...) {

    return Uploader.extend("my.custom.control.Uploader", {

        uploadItem: function (oItem, aHeaders) {
            // beginning of the method. take it from the official sources

            oXhr.onreadystatechange = function () {
                const oHandler = that._mRequestHandlers[oItem.getId()];
                if (this.readyState === window.XMLHttpRequest.DONE && !oHandler.aborted) {
                    // we need to return the xhr object. it contains the response!
                    that.fireUploadCompleted({ item: oItem, xhr: oXhr });
                }
            };

            // .. rest of the method
        }
    });
});

Use it like this


<mvc:View xmlns:custom="my.custom.control" ....>
    <UploadSet items="....">
        .....
        <uploader>
            <custom:Uploader uploadUrl="......"
                uploadCompleted=".onUploadCompleted"
                uploadStarted=".onUploadStarted" />
        </uploader>
    </UploadSet>

Edit: Your own uploader also means implementing your own event handlers (uploadAborted, uploadCompleted, uploadProgressed, uploadStarted). See the official documentation for more information about the events.