File upload with React, Express and Google Cloud Storage with folder structure
Faith Morante
Posted on November 23, 2019
For the front end, we will use FilePond. It has a plugin for React for file uploads that supports previews, validations, drag and drop, etc.
NOTE: This tutorial assumes that you know how to setup React and Express.
Start by yarn/npm installing these:
react-filepond
filepond
filepond-plugin-image-preview
filepond-plugin-image-exif-orientation
import { FilePond, registerPlugin } from "react-filepond"
import "filepond/dist/filepond.min.css"
import FilePondPluginImageExifOrientation from "filepond-plugin-image-exif-orientation"
import FilePondPluginImagePreview from "filepond-plugin-image-preview"
import "filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css"
Filepond component looks like this
<FilePond
files={imgCollection}
allowMultiple={true}
server={null}
instantUpload={false}
onupdatefiles={(fileItems) => onFileChange(fileItems)}>
</FilePond>
I use a form submit to trigger uploading of file/s.
Form:
<form onSubmit={onSubmit}>
<div className="form-group">
<button className="btn btn-primary" type="submit">Upload</button>
</div>
<div className="filepond-wrapper">
<FilePond
files={imgCollection}
allowMultiple={true}
server={null}
instantUpload={false}
onupdatefiles={(fileItems) => onFileChange(fileItems)}>
</FilePond>
</div>
</form>
Functions and states:
const [imgCollection, setImgCollection] = useState('')
const onFileChange = (files) => {
let items = files.map(fileItem => fileItem.file)
setImgCollection([...imgCollection, items])
}
const onSubmit = (e) => {
e.preventDefault()
var formData = new FormData()
for (let img in imgCollection[0]) {
formData.append('imgCollection', imgCollection[0][img])
}
formData.append('folder', 'folder-name')
axios.post(`${process.env.REACT_APP_API_ENDPOINT}/`, formData, {
}).then(res => {
console.log(res.data)
})
}
Install multer
in your api folder.
In your Express API:
var express = require('express');
var router = express.Router();
var path = require('path')
var multer = require('multer')
var upload = multer().array('imgCollection')
router.post('/', function(req, res, next) {
// Imports the Google Cloud client library.
const {Storage} = require('@google-cloud/storage');
const storage = new Storage({projectId: 'gcp-project-id', keyFilename: path.join(__dirname, '../creds.json')});
try {
async function uploadFile(file, folder) {
let bucketName = 'bucket-name'
let bucket = storage.bucket(bucketName)
let newFileName = folder + '/' + file.originalname;
let fileUpload = bucket.file(newFileName);
const blobStream = fileUpload.createWriteStream({
metadata: {
contentType: file.mimetype
}
});
blobStream.on('error', (error) => {
console.log('Something is wrong! Unable to upload at the moment.' + error);
});
blobStream.on('finish', () => {
const url = `https://storage.googleapis.com/${bucket.name}/${fileUpload.name}`; //image url from firebase server
console.log(url)
});
blobStream.end(file.buffer);
}
upload(req, res, function(err) {
let files = req.files
for (let file in files) {
uploadFile(files[file], req.body.folder)
}
if(err) {
return res.end("Error uploading file." + err);
}
res.end("File is uploaded");
})
} catch (err) {
res.send(err)
}
});
module.exports = router;
And that's it!
Hope you liked it.
Rock on,
FM
💖 💪 🙅 🚩
Faith Morante
Posted on November 23, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
googlecloudstorage File upload with React, Express and Google Cloud Storage with folder structure
November 23, 2019