0

I'm currently working on a React application and want to upload an image to the server. So I decided to use Axios on the client side and Multer on the server side. Here are my codes.

client side

import React, { useState } from 'react';
import './uploadPhoto.css';
const axios = require('axios');

const UploadPhoto = () => {
    const [selectedImage, setSelectedImage] = useState(null);
    const [text, setText] = useState('');

    const submitPhoto = (event) => {
        event.preventDefault();

        //TODO: Add a check to make sure the user has selected an image and send the photo to the server
        const formData = new FormData();
        formData.append('image', selectedImage);

        console.log(formData.get('image'));

        axios.post('http://localhost:3000/photo', formData)
        .then((response) => {
            // setText(response.data.pixels);
            console.log("Image sent successfully");
        })
        .catch((error) => {
            console.log(error.response.data);
            console.log(error.response.status);
            console.log(error.response.headers);
        });
    }

    return (
        <div className='UploadPhoto'>
            <form encType='multipart/form-data' onSubmit={ submitPhoto }>
                <input type="file" name='image' onChange={(event) => {
                    setSelectedImage(event.target.files[0]);
                }}/>
                <input type="submit" value="Submit"/>
            </form>
        </div>
    );
}

server side

const express = require('express');
const multer = require('multer');
const cors = require('cors');

const port = 3000;
const app = express();

app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(cors());

const upload = multer({ 
  storage: multer.memoryStorage(),
  limits: {
    fileSize: 1024 * 1024 * 10
  }
});

app.post('/photo', upload.single('image'), (req, res, next) => {
  console.log(req.file);

  const file = req.file;

  if(!file) {
    const error = new Error('Please upload a file');
    error.httpStatusCode = 400;
    console.log(error);
    return next(error);
  }
});

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

I'm encountering an error that req.file is undefined. In the console, I also see that Axios is giving an error code of 500. I've gone through virtually every stackoverflow and troubleshooting guide on Google but still no luck.

The error logs

console.log(error.response.data);

dispatchXhrRequest  @   C:\Users\user\Docume…node\axios.cjs:3389
xhr @   C:\Users\user\Docume…node\axios.cjs:3191
dispatchRequest @   C:\Users\user\Docume…node\axios.cjs:3489
request @   C:\Users\user\Docume…node\axios.cjs:3839
httpMethod  @   C:\Users\user\Docume…node\axios.cjs:3878
wrap    @   C:\Users\user\Docume…t\node\axios.cjs:29
onSubmit    @   uploadPhoto.js:18
callCallback    @   C:\Users\user\Docume…development.js:4164
invokeGuardedCallbackDev    @   C:\Users\user\Docume…development.js:4213
invokeGuardedCallback   @   C:\Users\user\Docume…development.js:4277
invokeGuardedCallbackAndCatchFirstError @   C:\Users\user\Docume…development.js:4291
executeDispatch @   C:\Users\user\Docume…development.js:9041
processDispatchQueueItemsInOrder    @   C:\Users\user\Docume…development.js:9073
processDispatchQueue    @   C:\Users\user\Docume…development.js:9086
dispatchEventsForPlugins    @   C:\Users\user\Docume…development.js:9097
(anonymous) @   C:\Users\user\Docume…development.js:9288
batchedUpdates$1    @   C:\Users\user\Docume…evelopment.js:26140
batchedUpdates  @   C:\Users\user\Docume…development.js:3991
dispatchEventForPluginEventSystem   @   C:\Users\user\Docume…development.js:9287
dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay @   C:\Users\user\Docume…development.js:6465
dispatchEvent   @   C:\Users\user\Docume…development.js:6457
dispatchDiscreteEvent   @   C:\Users\user\Docume…development.js:6430

error.response.status

Error: Please upload a file
[1]     at C:\Users\user\Documents\Project Intern\project-intern\backend\server.js:54:19
[1]     at Layer.handle [as handle_request] (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\layer.js:95:5)
[1]     at next (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\route.js:144:13)
[1]     at multerMiddleware (C:\Users\user\Documents\Project Intern\project-intern\node_modules\multer\lib\make-middleware.js:13:41)
[1]     at Layer.handle [as handle_request] (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\layer.js:95:5)
[1]     at next (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\route.js:144:13)
[1]     at Route.dispatch (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\route.js:114:3)
[1]     at Layer.handle [as handle_request] (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\layer.js:95:5)
[1]     at C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\index.js:284:15
[1]     at Function.process_params (C:\Users\user\Documents\Project Intern\project-intern\node_modules\express\lib\router\index.js:346:12)

error.response.headers

AxiosHeaders 
access-control-allow-origin : "*"
connection : "keep-alive"
content-length : "1525"
content-security-policy : "default-src 'none'"
content-type : "text/html; charset=utf-8"
date : "Tue, 14 Mar 2023 04:15:57 GMT"
keep-alive : "timeout=5"
x-content-type-options : "nosniff"
x-powered-by : "Express"
Symbol(Symbol.toStringTag) : (...)
[[Prototype]] : Object

Appreciate for any help in advance.

InvalidHop
  • 104
  • 1
  • 10
  • Why mix `import` and `require` in your React code? – Phil Mar 14 '23 at 03:48
  • What port is your React dev server running on? I only ask is it's typically port 3000 but you are using that for Express – Phil Mar 14 '23 at 03:52
  • I was running out of ideas, I initially used import. After a lot of debugging but still no luck, so I thought of just trial and error – InvalidHop Mar 14 '23 at 03:54
  • Is your image possibly larger than your filesize limit? – jfriend00 Mar 14 '23 at 03:55
  • @Phil I did not know there's a react dev server. How do I check that? FYI, I also have other post methods to handle simple text data (For testing purposes only). Those post methods worked fine – InvalidHop Mar 14 '23 at 03:56
  • @jfriend00 I'm currently testing with a very small picture of 11.7KB. I believe I have set the filesize limit to 10MB, right? I hope I'm not tripping haha – InvalidHop Mar 14 '23 at 03:58
  • 1
    I ran your code and it is working fine, for larger files, it shows error of too large file, and for normal file, it is returning the req.file – Srushti Shah Mar 14 '23 at 04:02
  • @Casual_R if other API calls are working then it's probably not a problem. FYI you can see what port the dev-server uses by looking at the address in your browser... `http://localhost:/` – Phil Mar 14 '23 at 04:09
  • 1
    Could you please [edit] your question to show what each of those `console.log()` lines in the `.catch()` callback shows? Please also check the terminal where you're running Express; an unhandled general error will typically log some details – Phil Mar 14 '23 at 04:12
  • Also, you could try simply removing the limit to eliminate that as a problem – Phil Mar 14 '23 at 04:16
  • @Phil I have included the log messages you asked for. As for the limit, did you filesize limit? If it is, I initially did not include the limit, but thought that it could be a limit problem hence I set it to 10MB – InvalidHop Mar 14 '23 at 04:24

0 Answers0