0

here is my server.js code:

const express = require('express');
const cors = require('cors');
const fileUpload = require('express-fileupload');
const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());
app.use(fileUpload());

app.post('/upload', (req, res) => {
  if(req.files === null) {
    return res.status(400).json({ msg: 'No file uploaded' })
  }

  const file = req.files.file

  file.mv(`${__dirname}/uploads/${file.name}`, err => {
    if(err) {
      console.error(err)
      return res.status(500).send(err)
    }

    res.json({ fileName: file.name, filePath: `/uploads/${file.name}` })
  })

});

app.listen(PORT, () => {
  console.log(`Server started on port ${PORT}`);
});

And here is my client side react code:

import React, { Fragment, useState } from 'react'
import axios from 'axios'
import Message from './Message'
import Progress from './Progress'


const FileUpload = () => {

    const [file, setFile] = useState({})
    const [filename, setFilename] = useState('Choose File')
    const [message, setMessage] = useState('') 
    const [uploadPercentage, setUploadPercentage] = useState(0)
    const [offset, setOffset] = useState(0)
    const [fileLength, setFileLength] = useState(0)

    const onChange = e => {
        setFile(e.target.files[0])
        setFilename(e.target.files[0].name) 
        setFileLength(file.size)
    }
    console.log(file.size)

    const onSubmit = async e => {
        e.preventDefault()
        const formData = new FormData()
        formData.append('file', file)

        try {
            const res = await axios.post('http://localhost:5000/upload', formData, {
                headers: {
                    'Content-Type': 'multipart/form-data',
                    'x-file-offset': {offset},
                    'x-file-length': {fileLength}
                },
                onUploadProgress: ProgressEvent => {
                     setUploadPercentage(parseInt(Math.round((ProgressEvent.loaded * 100) / ProgressEvent.total)))
                     setOffset(ProgressEvent.loaded)
                     // Clear percentage
                     setTimeout(() => {
                         setUploadPercentage(0)
                         setMessage('')
                     }, 10000);
                },

            })

            const { fileName, filePath } = res.data

            setUploadedFile({ fileName, filePath })

            setMessage('File Uploaded')

        } catch (error) {
            if(error.response) {
                setMessage('There was a problem with the server')
            } else {
                setMessage(error.response.data.msg)
            }
        }
    }

  return (
      <Fragment>
        { message ? <Message msg={message} /> : null }
        <form onSubmit={onSubmit}>
            <label className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" htmlFor="file_input">{filename}</label>
            <Progress percentage={uploadPercentage} />
            <input className="block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer bg-gray-50 dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400" id="file_input" type="file" onChange={onChange} />
            <button type='submit' value='Upload' className='py-2 px-5 mt-3 bg-green-400'>Upload</button>
        </form>
         
    </Fragment>
  )
}

export default FileUpload


This code works perfectly. I want to modify this code where the client side first checks how much of the file has been uploaded to the server already, slices the file accordingly and uploads that specific part. On the other hand, the server code stores the file and if it is not completed, it sends the offset data to let the client know how much of the file it has to yet to send.

I guess it will be implemented using filestream, arrayBuffer on the client side and maintaining some sort of offset (bytesUploaded) data on the backend. And it all has something to do with buffer data that express-fileupload provides of the file.

Functionality: If the user uploads a file, and refreshes the browser halfway and re-uploads, the upload and progress bar should start right where it left off before the browser refresh.

I tried implementing it the vanilla way using youtube tutorials where one was using busboy and the other was using angular with no package on backend side. I want to implement it using express-fileupload package and react.

0 Answers0