简体   繁体   中英

if statement is not working while the condition is true

I am learning to react js with typescript. The function I wrote uploads the images into firebase when the action submits button is clicked and it returns an array of URLs. Everything works fine but it takes a lot of time. In the if statement, I do not want to go to the if statement until the upload is complete since I need to put the URLs array into the product object. I have used promises and async-await but it is not working while the state is true.

If you want you can see the live code: https://codesandbox.io/s/eloquent-pine-tdv3wf?file=/src/AddProduct.tsx:1864-2218

This is the function that will set the state of the URLs into an array. Also, I have created promises after the success it will set true into the setSuccess state.

//States
 const [success, setSuccess] = useState<boolean>(false)
 const [images, setImages] = useState<any>([])
 const [URLs, setURLs] = useState<any>([])

  const uploadFiles = async (files: any) => {
  

        const promises: any = []
        files.map((file: any) => {

            const sotrageRef = ref(storage, `files/${file.name}`);
            const uploadTask = uploadBytesResumable(sotrageRef, file);
            promises.push(uploadTask)
            uploadTask.on(
                "state_changed",
                (snapshot: any) => {
                    const prog = Math.round(
                        (snapshot.bytesTransferred / snapshot.totalBytes) * 100
                    );
                    setProgress(prog);
                },
                (error: any) => console.log(error),
                async () => {
                   await getDownloadURL(uploadTask.snapshot.ref).then((downloadURLs: any) => {
                        setURLs((prevState: any) => [...prevState, downloadURLs])
                        console.log("File available at", downloadURLs);
                    });
                }
            );


        })
      
        try {
            await Promise.all(promises);
            setSuccess(true);
            return true;
        } catch (e) {
            console.error(e);
            return false;
        }
    };

After clicking on submit action button this handleProductSubmit function will call and then it will call the uploadfiles function to set the uploaded files URLs into an array. If the success state is true then it will go to the next step for adding the URLs into my product data. **The problem is it goes to the next step because uploadWasSuccessful is true but my URLs array is still empty. After this, if statement my URLs state set the urls **

   const handleProductSubmit = async (e: any) => {
        e.preventDefault()
        const uploadWasSuccessful: any = await uploadFiles(images)
        console.log('uploadWasSuccessful', uploadWasSuccessful);

        if (uploadWasSuccessful) {
            const newProductValue = { ...productValue, URLs }
            console.log(newProductValue, 'productValue');
        }

    }

The issue is here: setURLs state takes the URLs after rendering all my functions. Basically, it takes time to upload the files, and then it sets the URLs of the file.

async () => {
    await getDownloadURL(uploadTask.snapshot.ref).then((downloadURLs: any) => {
       setURLs((prevState: any) => [...prevState, downloadURLs])
       console.log("File available at", downloadURLs);
                    });

uploadFiles is asynchronous, so you need to wait until everything is finished there before continuing:

const handleProductSubmit = async (e: any) => {
  e.preventDefault()

  const uploadWasSuccessful = await uploadFiles(images)

  if (uploadWasSuccessful) {
    const newProductValue = { ...productValue, URLs }
    console.log(newProductValue, 'newProductValue');
  }
}

Then change uploadFiles to return the result instead of setting state (unless you need that state in other places, in which case both set the state and return the value):

const uploadFiles = async (files: any) => {
  // ... snip ...
  try {
    await Promise.all(promises);
    setSuccess(true);
    return true;
  } catch (e) {
    console.error(e);
    return false;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM