Upload Image in MySQL database using Node js and React js

In this article, we will learn how to upload an image in React and Node using a library called Multer. So we will upload an image and insert a record in the MySQL database by using React frontend.
We will also learn how to view an image on the frontend.

Frontend
We will create a basic client-side React app and then upload an image by creating an API in Node.js using Multer.

  1.  We will first create a React app boilerplate as follows.
    npx install create-react-app frontend
    It will take some time to install. Once the installation is complete create a simple upload form in App.js.
  2. Create a simple form to upload an image in app.js
    return (
    <div className='App'>
    <h1>Upload to server</h1>
    {image.preview && <img src={image.preview} width='100' height='100' />}
    <hr></hr>
    <form onSubmit={handleSubmit}>
    <input type="file" name="imageFile" multiple onChange={onSelectFile} accept="image/png , image/jpeg, image/webp"/>
    </div>
    )
  3. Now we have to create 2 methods:
    1. handleSubmit() : To submit the image data to the server.
    2. onSelectFile() :  It will be triggered when the user selects the image file. It will display the image preview and store the image data in the state. 
    const App = () => {
const [image, setImage] = useState({ preview: '', data: '' })
const onSelectFile = (e) => {
const img = {
preview: URL.createObjectURL(e.target.files[0]),
data: e.target.files[0],
}
setImage(img)
};
const handleSubmit =async (e) => {
e.preventDefault();
let formData = new FormData();
formData.append("imageFile", image.data);
const response = await fetch('http://localhost:5000/imageUpload', {
method: 'POST',
body: formData,
})
if (response) setStatus(response.statusText)
// }
};
}

         Now go to the terminal and run npm start. You will see an image upload form.

Backend
Here we are using Multer which will handle "multipart/form-data" sent from our form at frontend.

  1. Create a file user.model.js and paste the following code into it. This will create tables in the MySQL database when the backend server is started.

    –user.model.js

    module.exports = (sequelize, Sequelize) => {
    const user = sequelize.define("user", {
    imageFile: {
     type: Sequelize.TEXT('long'),
    }});return user;}; >
  2. Create a file user.routes.js and paste the following code into it. In this code first, we are using Multer to upload the image in the uploads folder. We have imported the user.controller at the top which we will create in the next step. Then we created a route “/imageUpload” in which we are uploading an image using upload.fields. The field name must be the same as the input element in the frontend. Here the name is  imageFile”.
    –user.router.js
    const users = require("./user.Controller");
    const multer = require("multer");
    var storage = multer.diskStorage({
    destination: function (req, file, cb) {
    cb(null, "./uploads");
    },
    filename: function (req, file, cb) {
    cb(null, file.originalname);
    },
    });
    var upload = multer({ storage: storage });
    module.exports = (app) => {
    router.post("/imageUpload", upload.fields([
    { name: "imageFile" }
    ]), users.createUser);
    }
  3. Now create a file named user.Controller.js. Inside that, we are creating a method to create learning. Inside this function we will access the path of the image from the request which is: req?.files?.imageFile[0].path

    –user.controller.js
    const createLearn = async (req, res) => {
       const saveLearnblogs = await LearnBlogs.create({
         imageFile: req?.files?.imageFile[0].path,
     })
    }
    review: URL.createObjectURL(e.target.files[0]),
    data: e.target.files[0],
    }
    setImage(img)
    };
    <div className="formInput">
    <label>Document</label>
    {/* <img src={file} /> */}
    {/* <input type="file" multiple={false} onChange={onSelectFile} name="imageFile" /> */}
    <input type="file" name="imageFile" multiple onChange={onSelectFile} accept="image/png , image/jpeg, image/webp" style={{ display: "none" }} />
    {/* <img src={file.preview} /> */}
    {selectedImages && selectedImages.map((image) => {
    return (
    <div key={image} className="image">
    <img src={image} alt="upload" />
    </div>
    );
    })}
    </div>
    Now create a .env file where you will create a base URL of all the APIs. This URL will be used to fetch the image on the frontend view.

      .env

REACT_APP_BASE_API_URL=http://localhost:4249/

Now create a UserProfile.js functional component and paste the following code into it. Here we are passing the image file as props to the component which is then used to fetch the path of the image.

LearnCard.js

function UserProfile({imageFile}) {
return (
<div>
<div className="p-5 m-3">
<img
src={`${REACT_APP_BASE_API_URL}${imageFile}`}
alt=""
width="400px"
/>
</div>
</div>
);
}

Now you can call the UserProfile component inside App.js to display the uploaded image.