0

I'm new to async and await, I have a simple web app with firebase which gets files through input fields and upload them to the firebase via a button click but when I click button it does,t wait for async function to uload the files at first click. But when I click second time the files uploaded and I got the expected output. How can I solve this? Here are my codes

Upload Function

async function uploadImages() {
        var storageRef = firebase.storage().ref();
        var uploadImages = document.getElementsByName("fupload").forEach((element) => {
            var imageRef = storageRef.child(
                "projects/" + projectName + "/" + (element as HTMLInputElement).files[0].name
            );
            let file = (element as HTMLInputElement).files[0];
            imageRef.put(file).then((snapshot) => {
                snapshot.ref.getDownloadURL().then(function (downloadURL) {
                    paragraphUrl.push(downloadURL);
                });
            });
        });

        if (document.getElementsByName("fupload").length == paragraphUrl.length) {
            return paragraphUrl;
        } else {
            return 1;
        }
    }

Button click function

async function upload(){
        await uploadImages().then((data) => {
            if (data != 1) {
                paragraphData = paragraphData.map(
                    function (x, i) {
                        return {
                            Title: x.Title,
                            Paragraph: x.Paragraph,
                            Image: data[i],
                        };
                    }.bind(this)
                );
                console.log(paragraphData);

                //dispatch("paragraphData",{data})
            } else {
                console.log("d");
            }
        });
}
  • Did you call `upload` with `await upload()` or `upload().then(something)` ? (Or possibly neither, which may be the problem.) – Wyck Apr 14 '21 at 18:25
  • 2
    Your question is strangely organised: under the heading **Upload function** we see some code (not a function), and under the heading **Button click function**, we see a function named `upload`. Then there is a variable `uploadImages` which always will be assigned `undefined`, and yet in your `upload` function, you *call* it as a function... I cannot make sense of this. – trincot Apr 14 '21 at 18:35
  • `uploadImages` does not appear to be/return a promise. Have a look at https://stackoverflow.com/q/37576685/1048572 as well. – Bergi Apr 14 '21 at 19:25
  • The problem I have is the await function executes before the file gets uploaded and returns a undefined value – Geethmaka Dissanayake Apr 15 '21 at 15:11
  • you haven't awaited this chain: `imageRef.put(file)` - since you have async-await - remove the `.then` chain. – Daniel A. White Apr 15 '21 at 15:13

1 Answers1

0

Thank you all I fixed the problem I'll add my code below.

Upload function

    async function uploadImages() {
        var storageRef = firebase.storage().ref();
        for (const file of document.getElementsByName("fupload")) {
            // let test = (file as HTMLInputElement).files[0].name;
            // console.log(test);
            var imageRef = storageRef.child(
                "projects/" + projectName + "/" + (file as HTMLInputElement).files[0].name
            );
            let test = (file as HTMLInputElement).files[0].name;
            let testFile = (file as HTMLInputElement).files[0];
            await imageRef.put(testFile).then((snapshot) => {
                snapshot.ref.getDownloadURL().then(function (downloadURL) {
                    paragraphUrl.push(downloadURL);
                });
            });
        }
        return paragraphUrl;
}

Button Click function

    async function submitParagraphData() {
        paragraphTitles = [];
        paragraphs = [];
        var e = document.getElementsByName("ParagrphTitle").forEach((element) => {
            paragraphTitles.push((element as HTMLInputElement).value);
        });
        var f = document.getElementsByName("Paragraph").forEach((element) => {
            paragraphs.push((element as HTMLInputElement).value);
        });

        let paragraphData = paragraphTitles.map(
            function (x, i) {
                return { Title: x, Paragraph: paragraphs[i] };
            }.bind(this)
        );

        await uploadImages().then((data) => {
            console.log(data);
        });
    }

The problem I had was when I click the button it displayed an empty array because file upload takes some time but when I click second time it displays the expected output because file was uploaded. So I added await to the line

imageRef.put(testFile) ............

So it fixed my problem.Thank you all for the support.