i have a create productForm component in react and when i upload images, it didn´t save the image and the data on the DB, only error message,
Server.js
// Instanciando dependências
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const cors = require('cors');
const productRoutes = require('./routes/productRoutes');
const adminRoutes = require('./routes/AdminRoutes');
// Iniciando servidor express
const app = express();
const PORT = process.env.PORT || 3000;
// Configurando middlewares
app.use(bodyParser.json());
app.use(cors());
// Servir arquivos estáticos (imagens)
app.use('/uploads', express.static('uploads'));
// Usar as rotas
app.use('/api', productRoutes);
app.use('/api', adminRoutes);
// Conexão com MongoDB
mongoose.connect('mongodb://localhost:27017/impermaq', {
useNewUrlParser: true,
useUnifiedTopology: true,
});
// Verificação na conexão do MongoDB
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
console.log('Connected to MongoDB');
});
// Inicializar servidor
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
ProductRoutes.js
const express = require('express');
const multer = require('multer');
const router = express.Router();
const Product = require('../models/Product');
// Configuração do multer para armazenamento de arquivos
const storage = multer.diskStorage({
destination: function (req, file, cb) {
// Caminho para o diretório uploads
cb(null, path.join(__dirname, '/uploads'));
},
filename: function (req, file, cb) {
cb(null, Date.now() + '-' + file.originalname);
}
});
const upload = multer({ storage: storage });
// CREATE - Criar um novo produto
router.post('/products', upload.array('images', 5), async (req, res) => {
try {
const productData = req.body;
if (req.files) {
productData.images = req.files.map(file => `/uploads/${file.filename}`); // Salvar caminhos das imagens
}
const product = new Product(productData);
await product.save();
res.status(201).send(product);
} catch (error) {
console.error(error); // Log de erro para debug
res.status(500).send({ error: 'Failed to create product', details: error.message });
}
});
// READ - Obter todos os produtos
router.get('/products', async (req, res) => {
try {
const products = await Product.find({});
res.status(200).send(products);
} catch (error) {
res.status(500).send(error);
}
});
// READ - Obter um produto pelo ID
router.get('/products/:id', async (req, res) => {
try {
const product = await Product.findById(req.params.id);
if (!product) {
return res.status(404).send();
}
res.status(200).send(product);
} catch (error) {
res.status(500).send(error);
}
});
// UPDATE - Atualizar um produto pelo ID
router.put('/products/:id', upload.single('image'), async (req, res) => {
try {
const productData = req.body;
if (req.file) {
productData.image_main = req.file.path; // Atualize o caminho da imagem principal
}
const updatedProduct = await Product.findByIdAndUpdate(req.params.id, productData, { new: true });
if (!updatedProduct) {
return res.status(404).send({ message: 'Product not found' });
}
res.status(200).send(updatedProduct);
} catch (error) {
res.status(500).send({ message: 'Failed to update product', error });
}
});
// DELETE - Deletar um produto pelo ID
router.delete('/products/:id', async (req, res) => {
try {
const product = await Product.findByIdAndDelete(req.params.id);
if (!product) {
return res.status(404).send();
}
res.status(200).send(product);
} catch (error) {
res.status(500).send(error);
}
});
module.exports = router;
ProductForm.jsx
import { Form, Input, Radio, Upload, Button, message } from 'antd';
import { PlusOutlined } from '@ant-design/icons';
const { TextArea } = Input;
const CreateProductForm = () => {
const [form] = Form.useForm();
const normFile = (e) => {
if (Array.isArray(e)) {
return e;
}
return e?.fileList;
};
const handleSubmit = async (values) => {
try {
const formData = new FormData();
formData.append('name', values.nome);
formData.append('description', values.descricao);
formData.append('specifications', values.detalhes);
formData.append('accessories', values.acessorios);
formData.append('condition', values.condicao);
if (values.imagens) {
values.imagens.forEach((file) => {
formData.append('images', file.originFileObj);
});
}
const response = await fetch('http://localhost:3000/api/products', {
method: 'POST',
body: formData,
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.details || 'Failed to create product');
}
message.success('Produto criado com sucesso!');
form.resetFields();
} catch (error) {
message.error(error.message);
}
};
return (
<Form
form={form}
layout="horizontal"
style={{ maxWidth: 600 }}
initialValues={{
condicao: 'Novo',
}}
onFinish={handleSubmit}
>
<Form.Item
label="Nome"
name="nome"
rules={[{ required: true, message: 'Por favor, insira o nome do produto!' }]}
>
<Input />
</Form.Item>
<Form.Item
label="Imagens"
name="imagens"
valuePropName="fileList"
getValueFromEvent={normFile}
>
<Upload listType="picture-card" beforeUpload={() => false} multiple>
<button
style={{
border: 0,
background: 'none',
}}
type="button"
>
<PlusOutlined />
<div
style={{
marginTop: 8,
}}
>
Adicionar Imagens
</div>
</button>
</Upload>
</Form.Item>
<Form.Item label="Descrição" name="descricao">
<TextArea rows={4} />
</Form.Item>
<Form.Item label="Detalhes" name="detalhes">
<TextArea rows={4} />
</Form.Item>
<Form.Item label="Acessórios" name="acessorios">
<TextArea rows={4} />
</Form.Item>
<Form.Item label="Condição" name="condicao">
<Radio.Group>
<Radio value="Novo">Novo</Radio>
<Radio value="Usado">Usado</Radio>
</Radio.Group>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
Criar Produto
</Button>
</Form.Item>
</Form>
);
};
export default CreateProductForm;
i created a folder called uploads to save the images but when i test it on postman, he returns this error postman log error but the way is correct, because my project is splitted in 3 folders: server, client and uploads