DEV Community

lakshmyps
lakshmyps

Posted on

Upload file to AWS S3 Using React, Node.js

I am a self-paced learner and exploring to scale up my programming knowledge and skill. Recently I learned about s3 and tried working out an example of uploading files to s3 using Nodejs. In this example we provide the input file from the frontend and using multer to POST the file to server and upload the file to S3.

1. Create an AWS account(if you don't have one)
2. Create S3 Bucket
3. Endpoint for upload file S3(Nodejs-back end)
4. Create a React component(Reactjs-front end)

Create S3 Bucket

Go to AWS Management Console type S3 and click the S3 Service.

Click the create bucket button

Give the bucket name and select the your region. When you are choosing a bucket name there are some rules to follow. Follow the below link [https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html]

If you want enable the versions for the objects on the bucket choose the enable option otherwise, leave all other options to default and click the create bucket button.

You can see the message on S3 console the bucket is successfully created.
Image description

If you would like to do it in an automated way you can use AWS cli

The following mb command creates a bucket in a region specified by the region parameter.

aws s3 mb s3://your-bucketname --region your-region
output
make_bucket: s3://your-bucketname

Get your AWS credential follow this below link [https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/getting-your-credentials.html ]

Endpoint for upload file to S3(Nodejs-back end)

Now we have completed the AWS bucket creation step, let us create our simple Node server with an endpoint to upload files to S3. First we have to install the packages via npm or yarn express, aws-sdk, file-type,

multer is a node. js middleware for handling multipart/form-data , which is primarily used for uploading files.

dotenv file is used to separately store our credentials/keys secrets from source code.dotenvis a zero-dependency module that loads environment variables from a .env file into process.env.npm install dotenv.

require('dotenv').config()
const express = require('express');
const AWS = require('aws-sdk');
const fs = require('fs');
const fileType = require('file-type');
const multer  = require('multer')
const upload = multer({ dest: 'uploads/' })

const app = express();

var cors = require('cors');
var bodyParser = require("body-parser");

app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());



const bucketName = process.env.AWS_BUCKET_NAME
const region = process.env.AWS_BUCKET_REGION
const accessKeyId = process.env.AWS_ACCESS_KEY
const secretAccessKey = process.env.AWS_SECRET_KEY


const s3 = new AWS.S3({
    accessKeyId: accessKeyId,
    secretAccessKey: secretAccessKey,
    region:region
});
// app.get("/check", (req, res) => {
//     res.json({'message': 'ok'});
// })



app.post("/uploadfile", upload.single('file'), (req, res) => {
    // console.log(req);
    console.log(req.file);
    if (req.file == null) {
        return res.status(400).json({ 'message': 'Please 
            choose the file' })
     }

        var file = req.file
        // res.send(200);
        // res.sendStatus(201);

        const uploadImage=(file)=>{
            const fileStream 
                 =fs.createReadStream(file.path);

            const params = {
                Bucket: bucketName,
                Key: file.originalname,
                Body: fileStream,
            };

            s3.upload(params, function (err, data) {
                console.log(data)
                if (err) {
                    throw err
                }
                console.log(`File uploaded successfully. 
                              ${data.Location}`);
            });
        }
        uploadImage(file);
        return res.send(201)
})

// app.listen(3002);
app.listen(3002, () => {
    console.log("Server running on port 3002")
})

Enter fullscreen mode Exit fullscreen mode

Create a React component(Reactjs-front end)

Axios is a library that serves to create HTTP requests that are present externally. It allows us to communicate with APIs easily in our React apps.

import React, { Component } from 'react';
import axios from 'axios';

class Uploadimage extends Component {
    constructor(props) {
        super(props)
        this.state = {
            // Initially, no file is selected
            selectedFile: null,
            sucessmessage:" ",
            errormessage:" ",
        }
    }

    }
    onChange = (e) => {

        // Update the state
        this.setState({selectedFile: e.target.files[0]})
    }

    uploadFile = (e) => {
        e.preventDefault();

        // Create an object of formData
        let formData = new FormData();

        // Update the formData object

        formData.append('file', this.state.selectedFile);

        console.log(this.state.selectedFile);

        axios.post("http://localhost:3002/uploadfile", formData, { headers: {'Content-Type': 'multipart/form-data'}})
            .then((res) => {
                //console.log(res)
                if (res.status === 200)
                    return (this.setState({sucessmessage: "File uploaded successfullyS3"}))

            })
            .catch((error) => {
                //console.error(error.response);
                this.setState({errormessage:error.response.statusText+" Please select the file"})

            })

    };

    render() {
        return (

            <div>
                <form method="post" action="#" onSubmit={this.uploadFile} >
                    <input type="file" name="uploadfile" onChange={this.onChange}></input>
                    <p> {this.state.sucessmessage}</p>
                    <p>{this.state.errormessage}</p>
                    <button> upload</button>
                </form>
            </div>
        )
    }

}
export default Uploadimage;

Enter fullscreen mode Exit fullscreen mode

Code here
[https://github.com/lakshmyps/uploadfile-2-S3-frontend]
[https://github.com/lakshmyps/Uploadfile-2-S3-backend]

Oldest comments (0)