Await not working in react

I’m trying to upload the image in the firebase. But the problem is uploading the image and sending the data to the backend without waiting for it to finish.
I think await function is not working

        if(imageUpload){
         
            await uploadFile();
            console.log(url)
        }
export default function Postcreate() {

    const imgFileRef = useRef();
    const navigate = useNavigate()
    const [topic,setTopic] = useState("")
    const [body,setBody] = useState("")
    const [imageUpload, setImageUpload] = useState("");
    const [url,setUrl] = useState("")

    const [topicdata , setTopicData] = useState([]);


      const uploadFile = async () => {
        if (imageUpload == null) return;
        try{
          const imageRef = ref(storage, `posts/${imageUpload.name + v4()}`);
          await uploadBytes(imageRef, imageUpload).then((snapshot) => {
              getDownloadURL(snapshot.ref).then((imageurl) => {
                console.log(imageurl) //test
                setUrl(imageurl)
                
            });
          });
        }catch(err){
          console.log("imageUpload -", err);
        } 
    
      };

      const PostCreateData = async () =>{

        if(imageUpload){
         
            await uploadFile();
            console.log(url)
        }

        if(!topic || !body || !url){
          
            document.getElementById("createPost-alert").style.display = "flex";
            document.getElementById("createPost-alert").innerHTML = "Please fill all the field!";
            return
          }
          
                  fetch("/createpost",{
                      method:"post",
                      headers:{
                          "Content-Type":"application/json",
                          "Authorization":"Bearer " + localStorage.getItem("jwt")
                      },
                      body:JSON.stringify({
  
                        topic, 
                        body,
                        url
  
                      })
                  }).then(res=>res.json())
                  .then(data => {
  
                      if(data.error){ 
                            document.getElementById("createPost-alert").style.display = "flex";
                            document.getElementById("createPost-alert").innerHTML = data.error;  
                      }
                      else{
                        toast.success(data.message,{
                          hideProgressBar: true,
                          closeOnClick: true,
                          pauseOnHover: true,
                          draggable: true,
                          progress: undefined,
                        });
                        setTimeout(function(){
                          // window.location.replace('/');
                        },1000);
                      }
                        
                  }).catch((err)=>{
                    console.log("Error - ", err)
                  })

      }

      

  return (
    <div>
                {/* //For Tost Messages */}
                <ToastContainer />
       <div>
            <div class="card shadow-sm p-2 mb-5 bg-white rounded">
                    
                    <div>
                    
                    {/* //Create Drop Down using topic Tabale in DB */}
                    <select  
                    class="form-select mb-2 "  
                    name="topic" 
                    value={topic}
                    onChange={(e) => setTopic(e.target.value)}
                    >
                                  <option key="" value="" selected disabled hidden>Select Topic</option>
                      {topicdata.map(topicItem=>{
                         return(                                
                                    <option key={topicItem.topic} value={topicItem.topic}>{topicItem.topic}</option>
                         )
                      })}
                         </select>


                        <textarea class="min-vh-15 mb-2 resize-none post-create-textarea"    
                          name="w3review"  
                          placeholder="Say Something..."
                          value={body}
                          onChange={(e) => setBody(e.target.value)}
                          required
                          ></textarea>

                        {/* Alert */}
                        <div class="text-danger mb-1" id="createPost-alert" role="alert"></div>

                        
                        <div className="d-flex flex-row justify-content-between">
                            <input 
                                ref={imgFileRef}
                                className="d-none" 
                                type="file" 
                                onChange={(event) => {
                                  setImageUpload(event.target.files[0]);
                                }}
                            />        

                            <button  
                              onClick={() => imgFileRef.current.click()}
                              type="button" 
                              class="btn btn-outline-dark ImageUpload-btn"> 
                              <i class="fa-light fa-folder-image"></i> 
                              Add Image
                           </button>  

                            <div className="d-flex flex-row justify-content-end">
                                <button type="button" 
                                  class="btn btn-primary post-btn"
                                  onClick={() => PostCreateData() }
                                  >Post</button>
                            </div>
                        </div>
                    </div>
                </div>
       </div>
    </div>
  )
}


what do you mean, ‘await’ function is not working?!

do you mean your use of it?!

@bappyasif
First, I need to upload the image to the storage drive using uploadFile() and then get the URL and send it to the backend server.

  1. Upload the image - uploadFile()
  2. get URL
  3. Send the backend - fetch("/createpost",{…

But here the compiler sends the data backend while uploading the image without waiting for the upload to complete

uploadFile()

const uploadFile = async () => {
        if (imageUpload == null) return;
        try{
          const imageRef = ref(storage, `posts/${imageUpload.name + v4()}`);
          await uploadBytes(imageRef, imageUpload).then((snapshot) => {
              getDownloadURL(snapshot.ref).then((imageurl) => {
                console.log(imageurl) //test
                setUrl(imageurl)
                
            });
          });
        }catch(err){
          console.log("imageUpload -", err);
        } 
    
      };

PostCreateData with uploadFile() calling

const PostCreateData = async () =>{

        if(imageUpload){
         
            await uploadFile();  **//this point not wait to get URL** 
            console.log(url)
        }

fetch("/createpost",{
                      method:"post",
                      headers:{
                          "Content-Type":"application/json",
                          "Authorization":"Bearer " + localStorage.getItem("jwt")
                      },
                      body:JSON.stringify({
  
                        topic, 
                        body,
                        url
  
                      })
                  }).then(res=>res.json())
}

i understand what you mean, i encountered something similar, and then used 'hooks - useState and useEffect)

i made sure code flow doesnt move forward until ‘url is received from firebase storage’ for 'writing into firestore!!

if that makes any sense, i suppose you need to bring some sort of ‘logical gate’ before moving (writing into db) to next step in program flow!!

hope this was helpful, happy coding :slight_smile:

1 Like

i fix the error using useEffect


      useEffect(() => {

        if(url){
          PostCreate();
        }

      }, [url]);

full code

export default function Postcreate() {

    const imgFileRef = useRef();
    const navigate = useNavigate()
    const [topic,setTopic] = useState("")
    const [body,setBody] = useState("")
    const [imageUpload, setImageUpload] = useState("");
    const [url,setUrl] = useState("")

    const [topicdata , setTopicData] = useState([]);

    useEffect(() => {
       
        textareaResizing();
        getTopicData();

      }, []);

      useEffect(() => {

        if(url){
          PostCreate();
        }

      }, [url]);

      const getTopicData = () =>{
        fetch("/topic/get")
        .then(res=>res.json())
        .then(result=>{
          setTopicData(result.Topics);
        })
        .catch((err)=>{
           console.log("Error - ",err)
        })
      }

      const textareaResizing = () =>{
           // textarea auto resizing limit=250px
        const textarea = document.querySelector("textarea");
        textarea.addEventListener("keyup", e =>{
          textarea.style.height = `45px`
          let scHeight = e.target.scrollHeight;
            if(scHeight < 250){
                textarea.style.height = `${scHeight}px`;
            }
            else{
                textarea.style.height = `250px`
            }
        });
      }


      const uploadFile =  () => {
        if (imageUpload == null){
          return;
        }     
        else{
              const imageRef = ref(storage, `posts/${imageUpload.name + v4()}`);
               uploadBytes(imageRef, imageUpload).then((snapshot) => {
                  getDownloadURL(snapshot.ref).then((imageurl) => {
                    console.log(imageurl) //test
                    setUrl(imageurl)
                    
                });
              });
        }   
    
      };


      const PostCreateData =  () =>{

        if(imageUpload){
              uploadFile()
              console.log("URL - " + url)
        }
        else{
          PostCreate();
        }


      }

      const PostCreate = () =>{
        console.log("hello upload")
        if(!topic || !body ){
          
          document.getElementById("createPost-alert").style.display = "flex";
          document.getElementById("createPost-alert").innerHTML = "Please fill all the field!";
          return
        }
        
                fetch("/createpost",{
                    method:"post",
                    headers:{
                        "Content-Type":"application/json",
                        "Authorization":"Bearer " + localStorage.getItem("jwt")
                    },
                    body:JSON.stringify({

                      topic, 
                      body,
                      url

                    })
                }).then(res=>res.json())
                .then(data => {

                    if(data.error){ 
                          document.getElementById("createPost-alert").style.display = "flex";
                          document.getElementById("createPost-alert").innerHTML = data.error;  
                    }
                    else{
                      toast.success("Post Created",{
                        hideProgressBar: true,
                        closeOnClick: true,
                        pauseOnHover: true,
                        draggable: true,
                        progress: undefined,
                      });
                      setTimeout(function(){
                        window.location.replace('/');
                        navigate.push('/')
                      },1000);
                    }
                      
                }).catch((err)=>{
                  console.log("Error - ", err)
                })
      }
      

  return (
    <div>
                {/* //For Tost Messages */}
                <ToastContainer />
       <div>
            <div class="card shadow-sm p-2 mb-5 bg-white rounded">
                    
                    <div>
                    
                    {/* //Create Drop Down using topic Tabale in DB */}
                    <select  
                    class="form-select mb-2 "  
                    name="topic" 
                    value={topic}
                    onChange={(e) => setTopic(e.target.value)}
                    >
                                  <option key="" value="" selected disabled hidden>Select Topic</option>
                      {topicdata.map(topicItem=>{
                         return(                                
                                    <option key={topicItem.topic} value={topicItem.topic}>{topicItem.topic}</option>
                         )
                      })}
                         </select>


                        <textarea class="min-vh-15 mb-2 resize-none post-create-textarea"    
                          name="w3review"  
                          placeholder="Say Something..."
                          value={body}
                          onChange={(e) => setBody(e.target.value)}
                          required
                          ></textarea>

                        {/* Alert */}
                        <div class="text-danger mb-1" id="createPost-alert" role="alert"></div>

                        
                        <div className="d-flex flex-row justify-content-between">
                            <input 
                                ref={imgFileRef}
                                className="d-none" 
                                type="file" 
                                onChange={(event) => {
                                  setImageUpload(event.target.files[0]);
                                }}
                            />        

                            <button  
                              onClick={() => imgFileRef.current.click()}
                              type="button" 
                              class="btn btn-outline-dark ImageUpload-btn"> 
                              <i class="fa-light fa-folder-image"></i> 
                              Add Image
                           </button>  

                            <div className="d-flex flex-row justify-content-end">
                                <button type="button" 
                                  class="btn btn-primary post-btn"
                                  onClick={() => PostCreateData() }
                                  >Post</button>
                            </div>
                        </div>
                    </div>
                </div>
       </div>
    </div>
  )
}

Thanks @bappyasif

glad i could help, happy coding :slight_smile: