0

I'm developing a small application where user can upload multiple file by a common input file field.

When an user clicks to the "Submit" button, I'm running this code:

function UploadFiles() {
    var loadFiles = document.getElementById('selectedFile').files;
    for (var i=0; i<=loadFiles.length;i++){
        var fileOgg = loadFiles[i];
        if (fileOgg!=undefined || fileOgg!=null){

            new Promise(function (resolve, reject) { resolve (fileOgg); })
            .then(UploadFilesStep)
            .then(retrieveMetadata)
            .then(changeMetadata)
            .then(moveTo)
            .then(showSuccess); 
        }
    }    
}

This is the UploadFilesStep detail:

var UploadFilesStep = function (fileOgg) {
    return new Promise(function(resolve, reject) {
        pnp.setup({ headers: { "Cache-Control": "no-cache", }, });
        // This is a SharePoint PnP call to file upload
        pnp.sp.web.getFolderByServerRelativeUrl("/sites/mysite/Config").files.add(fileOgg.name, fileOgg, true).then(function(result) {
            console.log("FileUpload success");
            resolve([result, fileOgg]);
        });   
    })
}

The retrieveMetadata code:

var retrieveMetadata = function ([result, fileOgg]) {
    return new Promise(function(resolve, reject) {
        pnp.setup({ headers: { "Cache-Control": "no-cache", }, });
        result.file.listItemAllFields.get().then(function(listItemAllFields) {
            resolve([listItemAllFields, fileOgg]);
        });
    })
}

And this is the changeMetadata promise:

var changeMetadata = function ([listItemAllFields, fileOgg]) {
    return new Promise(function(resolve, reject) {
        pnp.setup({ headers: { "Cache-Control": "no-cache", }, });
        pnp.sp.web.lists.getByTitle("Config").items.getById(listItemAllFields.Id).update({
            Number: ""+number+"",
        }).then(function(r){
            console.log("Properties updated successfully! Go to MoveTo");
            resolve(fileOgg);
        });
    })
}

And finally the MoveTo code:

var moveTo = function (fileOgg) {
    return new Promise(function(resolve, reject) {
        var nameFile = fileOgg.name;
        var timestamp = + new Date();
        var fileName = nameFile.substr(0, nameFile.lastIndexOf('.'));
        var newFileName = fileName + "-" + timestamp;
        var sourceFileUrl = _spPageContextInfo.webServerRelativeUrl+"/Config/"+nameFile+"";
        var targetFileUrl = _spPageContextInfo.webServerRelativeUrl+"/Attachments/"+nameFile.replace(fileName, newFileName)+"";
        var headers = headers || {};
        var method = 'POST';
        headers["Accept"] = "application/json;odata=verbose";
        headers["X-RequestDigest"] = $("#__REQUESTDIGEST").val();
        var endpointUrl = siteurl2 + "/_api/web/GetFileByServerRelativeUrl('" + sourceFileUrl + "')/MoveTo(newurl='" + targetFileUrl + "',flags=1)";
        var payload;

        $.ajax({
            url: endpointUrl,
            type: method,
            contentType: "application/json;odata=verbose",
            data: JSON.stringify(payload),
            cache: false,
            headers: headers,
            async: false,
            success: function (data) {
                strResults += "";
                counterUpload = counterUpload + 1;
                resolve();
            },
            error: function (data) {
                strResults += "Error " + JSON.stringify(data, null, 4);;
                resolve();
            }
        });
    }); 
}

From console of my browser I can see that first two promises (UploadFilesStep and retrieveMetadata) are running with the correct order. Then, I can't see the changeMetadata log, but it seems going forward with the for loop in UploadFiles. After a while I receive the response from changeMetadata and it often returns a 404 error ("Error making HttpClient request in queryable" linked to pnp js file).

What am i doing wrong?

Pepozzo
  • 209
  • 1
  • 3
  • 16
  • 2
    You might want to read [What is the explicit promise construction antipattern and how do I avoid it?](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it) – Heretic Monkey Jul 15 '19 at 21:38
  • The loop doesn't wait for the promise to be fulfilled, if you want to do that (upload one file at a time) you'll have to use `async` - `await` or recursion. – Titus Jul 15 '19 at 21:44
  • Another problem with your initial function is that you have the common closure-in-a-loop problem: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures#Creating_closures_in_loops_A_common_mistake – Jack A. Jul 15 '19 at 21:49
  • add catch block in `changeMetadata, retrieveMetadata ` and reject promise from there otherwise promise will never finish if any error comes. *add `.catch` in UploadFiles also.* – Rahul Sharma Jul 16 '19 at 10:48

0 Answers0