React useEffect delayed only with file upload

Viewed 61

My file upload feature involves two components, ViewProjectAttachment to view list of attachments related to the project and AddAttachment, a form for uploading files. My files are stored in server side, public/images folder.

ViewProjectAttachment.js

import React, {useEffect, useState, useContext} from 'react'
import Axios from 'axios';
import {Col, Row, Button, Modal, Table, Form} from 'react-bootstrap';
import {Image} from 'cloudinary-react';
import { UserContext, UserTypeContext } from './../Helper/Context';
import { useHistory } from 'react-router-dom';


function ViewProjectAttachment({itemID, isBelong}) {

    var projectId = itemID;

    const {userId, setUserId} = useContext(UserContext);
    const {type, isUserType} = useContext(UserTypeContext);

    const history = useHistory();

    const [attachmentList, setAttachmentList] = useState([]);

    const [fileSelected, setFile] = useState();

    const [showModal, setShowModal] = useState(false);
    const handleClose = () => setShowModal(false);

    const [delAttachment, setDelAttachment] = useState (false);
    const handleDelete2 = () => setDelAttachment(false);

    useEffect(()=>{
        
        Axios.get(`http://localhost:3001/${projectId}/attachment`,{
            projectId: projectId,
        })
        .then((response) => {
            
            setAttachmentList(response.data);
            
        })
    },[attachmentList]);

    const addNewAtt = () => {
        if(type === 'Staff'){
            history.push(`/staff/${userId}/addattachment/${projectId}`);
        }
        else if(type === 'Student'){
            history.push(`/student/${userId}/addattachment/${projectId}`);
        }
    }

    const deleteAttachment = (e, attachment_id) => {

        e.preventDefault();

        const attachmentId = attachment_id;

        Axios.delete(`http://localhost:3001/delattachment/${attachmentId}`, {
            attachmentId: attachmentId,
        })
        .then((respon) => {
            
            handleDelete2();
            window.alert("Attachment has been deleted!");
            
         })
    }

  return (
    <div>
            <Row>
                <Col className = "d-flex justify-content-start fw-bold">
                    Attachment
                </Col>
                <Col className = "d-flex justify-content-end">
                    <Button variant="link" onClick={addNewAtt}>+ Add</Button>
                </Col>
            <hr/>
            </Row>
            <Form>
                            
                            <Form.Group className="mb-3" controlId="image">

                                <Form.Control type="file"
                                    onChange={(event) => {
                                        setFile(event.target.files[0]);
                                    }}
                                />
                            </Form.Group>

                            
                            <div className = "d-flex flex-end justify-content-end align-items-end mt-3">
                                <div>
                                    <Button onClick={uploadImage}>Save</Button>
                                </div>
                            </div>
                        </Form>
                </Row>

                    <Modal show={showModal} onHide={handleClose}>
                        <Modal.Header closeButton>
                        <Modal.Title>SUCCESSFUL</Modal.Title>
                        </Modal.Header>
                        <Modal.Body>You have successfully uploaded an image!</Modal.Body>
                        <Modal.Footer>
                        <Button variant="secondary" onClick={handleClose}>
                            Close
                        </Button>
                        </Modal.Footer>
        
    </div>
  )
}

export default ViewProjectAttachment

AddAttachment.js

import React, {useState, useContext} from 'react'
import {Form, Button, Card} from 'react-bootstrap'
import Axios from 'axios';
import { useHistory } from 'react-router-dom';
import { UserContext, UserTypeContext } from './../Helper/Context';

function AddAttachment() {

    const history = useHistory();

    const {userId, setUserId} = useContext(UserContext);
    const {type, isUserType} = useContext(UserTypeContext);

    const link = window.location.pathname;
    const split = link.split("/");
    const projectId = split[4];

    const [file, setFile] = useState();
    const [fileName, setFileName] = useState("");
 
      const saveFile = (event) => {

        event.preventDefault();
        setFile(event.target.files[0]);
        setFileName(event.target.files[0].name);
      };
 
      const uploadFile = async(e, projectId) => {

        e.preventDefault();

        const formData = new FormData();
        formData.append("file", file);
        formData.append("fileName", fileName);
        formData.append("projectId", projectId);
        try {
          const res = await Axios.post(
            "http://localhost:3001/uplatt",
            formData,
          ).then((res) => {
            if(res.data.successfulAdd){

                if(type === 'Staff'){
                    window.alert('You have successfully uploaded an attachment!');
                    history.push(`/staff/${userId}/viewproject/${projectId}`);
                }
                else if(type === 'Student'){
                    window.alert('You have successfully uploaded an attachment!');
                    history.push(`/student/${userId}/viewproject/${projectId}`);
             }
            }
          });


        } catch (ex) {
          console.log(ex);
        }


      };

    const backToProject = (e) => {
        e.preventDefault();

        if(type === 'Staff'){
            history.push(`/staff/${userId}/viewproject/${projectId}`);
        }
        else if(type === 'Student'){
            history.push(`/student/${userId}/viewproject/${projectId}`);
        }
    }

  return (
    <div className="d-flex justify-content-center">
            <Card style={{ width: '70%' }}>
            <div className = "mt-3 p-5">
                <h3>
                    Add new attachment
                </h3>
                <hr/>
                <Form onSubmit={(event) => uploadFile (event, projectId)}>
                <div className="mt-1 mb-3">
                    <input type="file" name="file" onChange={(e) => saveFile(e)} />
                </div>
                <div className = "d-flex flex-end justify-content-end align-items-end mt-3">
                    <div className = "px-3">
                    <Button type="button" style={{color:'white', backgroundColor:'#104271'}} onClick={backToProject} className = "mr-3">Cancel</Button>
                    </div>
                    <div>
                    <Button type="submit" style={{color:'white', backgroundColor:'#104271'}}>Upload</Button>
                    </div>
                </div>
                </Form>
            </div>
            </Card>
        </div>
  )
}

export default AddAttachment

Problem is, the attachmentList is not updated right after the file has been saved to database and server public folder. It took a few seconds to show, eventhough I have already added attachmentList as a dependency array in my useEffect. My back-end code:

app.get("/:projectId/attachment", function(req, res){

    const projectId = req.params.projectId;

    try{
        const findProjectAttachment = "SELECT project_attachment.project_attachment_id, project_attachment.project_attachment_url, project_attachment.project_id FROM project_attachment INNER JOIN project ON project_attachment.project_id=project.project_id WHERE project_attachment.project_id = ?;";

        db.query(findProjectAttachment, projectId, (err, result) => {

            if(result.length > 0){
                res.send(result);
            }
        }
        )
    }
    catch(err){
        console.log(err);
    }
});

This is also only happening with my upload feature. The others work just fine. Anyone?

1 Answers

You all, it was a very silly mistake. I should not have included if(result.length > 0) in my back-end code. So it should have been like this:

app.get("/:projectId/attachment", function(req, res){

    const projectId = req.params.projectId;

    try{
        const findProjectAttachment = "SELECT project_attachment.project_attachment_id, project_attachment.project_attachment_url, project_attachment.project_id FROM project_attachment INNER JOIN project ON project_attachment.project_id=project.project_id WHERE project_attachment.project_id = ?;";

        db.query(findProjectAttachment, projectId, (err, result) => {

                res.send(result);
            }
        )
    }
    catch(err){
        console.log(err);
    }
});

Related