When I clone my github project it doesn't work

Issue

Using a Flask API on a ReactJs website, I have 2 routes on my server.py file.

On the frontend I can upload a file to firebase storage. In server.py, I have a route that uses POSTed information about the filename after it’s uploaded, then downloads it from firebase.

# File download Link
@app.route('/filePath', methods=['POST'])
def get_path():
    data = request.get_json()["path"]
    storage.child(f"files/{data}").download(f"files/Resume.pdf")
    return "Success.."

Then I have another route that does some logic with the file after it’s been downloaded. The route then feeds the information to the frontend as such

# Details API Get Route
@app.route("/details")
def details():
    path = r"path\to\pdf"
    person_data = PersonAnalyser(path).get_data()
    return {"email":person_data.get('email'),
            "mobile_number":person_data.get('mobile_number'),
            "name":person_data.get('name'),
    }

My issue, is that the /details route is executed everytime the page loads up, before I can even upload a file. I’m not sure how I can change that.

Here’s how I’m calling it on the frontend

const FileUpload = () => {
    const [initialData, setInitialData] = useState([{}])
    const [progress, setProgress] = useState(0);
    const formHandler = (e) => {
      e.preventDefault();
      const file = e.target.files[0];
      uploadFiles(file);
      update();
    };

    const update = () => {
      axios.get('http://localhost:3000/details').then((res) => {
        setInitialData(res.data);
      });
    };

    useEffect(update, []);

I’m not sure if the rest is relevant or not so I’ll just post it, This is the entire FileUpload which I’m exporting and calling in App.jsx

const FileUpload = () => {
    const [initialData, setInitialData] = useState([{}])
    const [progress, setProgress] = useState(0);
    const formHandler = (e) => {
      e.preventDefault();
      const file = e.target.files[0];
      uploadFiles(file);
      update();
    };

    const update = () => {
      axios.get('http://localhost:3000/details').then((res) => {
        setInitialData(res.data);
      });
    };

    useEffect(update, []);
  
    const uploadFiles = (file) => {
      //
      if (!file) return;
      if (!initialData) return null;
      const storageRef = ref(storage, `files/${file.name}`);
      const uploadTask = uploadBytesResumable(storageRef, file);
  
      uploadTask.on(
        "state_changed",
        (snapshot) => {
          const prog = Math.round(
            (snapshot.bytesTransferred / snapshot.totalBytes) * 100
          );
          setProgress(prog);
        },
        (error) => console.log(error),
        () => {
          getDownloadURL(uploadTask.snapshot.ref).then(() => {
            axios.post('http://localhost:3000/filePath', {
              'path': file.name
            }).then(() => console.log(file.name));
          });
        }
      );
    };

    

    return (
        <>
            <div className="file-card">

                <div className="file-inputs">
                    <input type="file" onChange={formHandler} />
                    <button>
                        <i>
                            <FontAwesomeIcon icon={faPlus} />
                        </i>
                        Upload
                    </button>
                </div>
                <ProgressBar color={"#ff7979"} width={"150px"} value={Math.round(progress)} max={100} />
                <p className="main">Supported files</p>
                <p className="info">PDF, JPG, PNG</p>
            </div>
            <div>
              <h3>Hello {initialData.name}</h3>
            </div>
        </>
    )
}

export default FileUpload

Just to re-iterate, my problem is that /details is executed when the page loads which throws off the entire workflow. It needs to wait for /filePath to be called and finish executing to then start executing /details. Any suggestions please?

Solution

The below line is causing update() to run on page load. If you don’t want that then remove it:

useEffect(update, []);

To run it on /filePath complete, then I’d suggest the .then() for that axios call:

        axios.post('http://localhost:3000/filePath', {
          'path': file.name
        }).then(() => {
          console.log(file.name);
          update();
        });

In the formHandler, you are immediately calling update() after uploadFiles():

const formHandler = (e) => {
  ...
  uploadFiles(file);
  update();
};

This is a problem because uploadFiles() is async, meaning update() will run before uploadFiles() completes. If you move update() to the .then() as suggested above, then you can remove it from formHandler.

Answered By – MrCode

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published