1

Here I have 2 functions that will upload files to the firebase storage. So the process here is to upload the file and add that returned url to a array , and it is functioning as expected. But the problem here is if there were no file uploaded the,

            return new Promise((resolve, reject) => {
                if (type == "paragraph") {
                    resolve(paragraphUrl.push(""));
                }
                resolve("");
            });

part executes before the previous file upload and add a value to the array. How can I fix this?

Upload Image function

    let uploadImage = (reference, file, type, notDisabled) => {
        if (notDisabled) {
            if (type == "banner") {
                file = banner[0];
            } else if (type == "logo") {
                file = logo[0];
            } else if (type == "popup") {
                file = popupImage[0];
            }
            return new Promise((resolve, reject) => {
                let upload = reference.put(file).then((snapshot) => {
                    snapshot.ref.getDownloadURL().then((downloadURL) => {
                        if (type == "banner") data.bannerPath = downloadURL.toString();
                        else if (type == "logo") data.logo = downloadURL.toString();
                        else if (type == "popup") data.popupImage = downloadURL.toString();
                        else if (type == "paragraph") {
                            resolve(paragraphUrl.push(downloadURL));
                        }
                        resolve(downloadURL);
                    });
                });
            });
        } else {
            return new Promise((resolve, reject) => {
                if (type == "paragraph") {
                    resolve(paragraphUrl.push(""));
                }
                resolve("");
            });
        }
    };
function f1(){
        Promise.all([
            uploadImage(bannerRef, null, "banner", bannerAdded),
            uploadImage(logoRef, null, "logo", logoAdded),
            uploadImage(popupref, null, "popup", popUpAdded),
        ]).then(() => {
            data.name = name;
            data.url = url;
            data.description = description;
            if (document.getElementsByName("paragraphImageUpload").length != 0) {
                for (const file of document.getElementsByName("paragraphImageUpload")) {
                    let fileName, image, paragraphRef, fileAvailable;
                    if ((file as HTMLInputElement).files.length != 0) {
                        fileName = (file as HTMLInputElement).files[0].name;
                        image = (file as HTMLInputElement).files[0];
                        paragraphRef = storageRef.child("projects/" + url + "/" + fileName);
                        fileAvailable = true;
                    } else {
                        fileAvailable = false;
                    }
                    Promise.all([
                        uploadImage(paragraphRef, image, "paragraph", fileAvailable),
                    ]).then(() => {
                        paragraphData = paragraphData.map(
                            function (x, i) {
                                return {
                                    Title: x.Title,
                                    Paragraph: x.Paragraph,
                                    Image: paragraphUrl[i],
                                };
                            }.bind(this)
                        );
                        data.ParagraphData = paragraphData;
                        console.log(data);
                        firebase.firestore().collection("projects").doc(url).set(data);
                        alert("done");
                    });
                }
            } else {
                data.ParagraphData = paragraphData;
                firebase.firestore().collection("projects").doc(url).set(data);
                alert("done");
            }
        });
}
  • Am I missing something? You either check for "" and skip it, when you are handling the array after all promises are resolved (because that's the resolution when `notDisabled` is false (very confusing name btw)) or you let it reject, if not uploading is considered a failure. – Chris Wesseling May 12 '21 at 16:59
  • Actually what I want is I have 2 file uploads. So user can upload a file or not. If user doesn't upload a file to a upload array mus save the value "" otherwise it will save the returned url. The problem here is if a user uploaded a file to 1st upload and doesn't upload something for 2nd one the adding null value part executed first and array will look like this ["",retuned url] instead of [returned url, ""] – Geethmaka Dissanayake May 12 '21 at 17:21
  • Avoid the [`Promise` constructor antipattern](https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi May 12 '21 at 19:41
  • `resolve(paragraphUrl.push(…))` doesn't really make sense. Where is `paragraphUrl` even defined? Is it a global variable that you mutate? Why do you resolve the promise with the return value of the `push` call? You should resolve the promise with the url itself, and handle the value in the `.then()` callback in the caller. – Bergi May 12 '21 at 19:45
  • `Promise.all([ uploadImage(paragraphRef, image, "paragraph", fileAvailable), ])` doesn't make sense - there's only one promise in the array. – Bergi May 12 '21 at 19:47
  • 1
    Your actual problem appears to be that the asynchronous operations inside the `for (const file of document.getElementsByName("paragraphImageUpload"))` loop will be concurrent. – Bergi May 12 '21 at 19:47
  • @Bergi is there any other way to do it in sequence order? – Geethmaka Dissanayake May 13 '21 at 08:44
  • 2
    I'd recommend `async`/`await` – Bergi May 13 '21 at 11:29

0 Answers0