-1
I’m using middleware multer to upload files, but on the front end (with React.js) when using the form-data to get the files selected by the user , but I can’t send to the back-end, I’ve already tested the upload route with Insomnia and it worked fine , the problem lies in integrating with the same React. Data such as name, email and password usually arrive by formdata only files arrive empty (Empty).
multer.
import multer from 'multer'
import path from 'path'
const storage = multer.diskStorage({
destination: (req, file, callback) =>{
callback(null, path.resolve(__dirname, 'uploads') )
},
filename: (req, file, callback) =>{
callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
const uploads = multer({ storage: storage })
export default uploads
Usercontroller.ts
import { Request, Response } from 'express'
//import knex from '../database/conn'
class UserController {
async create(request: Request, response: Response){
response.json({
user_data: request.body,
files: request.files
})
}
}
export default UserController
Routes.
import express, { Router, Request, Response } from 'express'
import uploads from './multer'
import UserController from './controllers/UserController'
import MidiaController from './controllers/MidiaController'
const user_controller = new UserController()
const routes = express.Router()
//rota para cadastrado de usuário
routes.post('/cad-user', uploads.single('file'), user_controller.create)
export default routes
App.tsx
import React, { useState, ChangeEvent, FormEvent } from 'react';
import axios from 'axios'
import FormData from 'form-data'
import { Request, Response } from 'express'
import './app.css'
import styled from 'styled-components'
const Input = styled.input`
border: none;
border-bottom: 1px solid #a6a6a6;
font-size: 18px;
margin: 5px 0px 10px 0px;
outline: none;
background-color: transparent;
padding: 5px 10px;
`
const BtnSubmit = styled.input`
border: none;
border-radius: 3px;
padding: 8px 16px;
font-size: 15px;
color: #f1f1f1;
background-color: #2488C6;
width: 50%;
margin: 20px 0px 0px 0px;
cursor: pointer;
outline: none;
transition-duration: 0.4s;
&:hover{
opacity: 0.85;
};
`
const TitleForm = styled.h1`
width: 100%;
padding: 5px 0px 20px 0px;
text-align: center;
`
function App() {
const [file, setFile] = useState()
const [getFormData, setFormData] = useState({
nome: '',
email: '',
senha: ''
})
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) =>{
// console.log(event.target.name, event.target.value)
const { name, value } = event.target
setFormData({
...getFormData,
[ name ] : value
})
}
const handleInputFileChange = (e: any) =>{
setFile(e.target.files[0])
}
async function handleSubmit(event: FormEvent){
event.preventDefault()
console.log('Arquivo selecionado')
console.log(file)
const { nome, email, senha } = getFormData
let formData = new FormData()
formData.append('nome', nome)
formData.append('email', email)
formData.append('senha', senha)
formData.append('file', file)
axios({
url: 'http://localhost:3030/cad-user',
method: 'POST',
headers: { 'Content-Type': 'multipart/form-data' },
data: formData
})
.then(response =>{
console.log(response.data)
})
.catch(error =>{
console.error('Erro capturado: ' + error)
})
}
return (
<div className="App">
<form onSubmit={handleSubmit}>
<TitleForm>Envie seu relato</TitleForm>
<Input
type="text"
name="nome"
id="nome"
placeholder="Digite seu nome..."
onChange={handleInputChange}
multiple
/>
<Input
type="text"
name="email"
id="email"
placeholder="Digite seu email..."
onChange={handleInputChange}
/>
<Input
type="password"
name="senha"
id="senha"
placeholder="Digite sua senha..."
onChange={handleInputChange}
/>
<Input
type="file"
name="files"
id="files"
onChange={handleInputFileChange}
multiple
/>
<BtnSubmit type="submit" value="Enviar Memória"/>
</form>
</div>
);
}
export default App;
Remarks
Here I am assigning only the first file selected by the user, because I could not think of any way to send all at once , the idea at first would be to store in the database a single string containing all the links (path) of the files separated by ','(comma) to then be able to break this string with Function split, plus the main problem is related to the upload itself.
const handleInputFileChange = (e: any) =>{
setFile(e.target.files[0])
}
Form print
As you can see the files do not appear for the back-end. I already appreciate any kind of help, I have searched on several websites about uploading files with React and typescript , but unfortunately I have not succeeded yet.