Reactjs TypeError:无法读取属性';文件名';未定义的';创建用户时出现此错误';
我正在尝试创建一个具有个人资料图片的用户。我正在使用multer,我不知道如何使用multer,我只是按照文档进行了操作,但是当我试图创建一个带有配置文件图片的用户时,它显示了一个错误Reactjs TypeError:无法读取属性';文件名';未定义的';创建用户时出现此错误';,reactjs,express,mongoose,react-redux,multer,Reactjs,Express,Mongoose,React Redux,Multer,我正在尝试创建一个具有个人资料图片的用户。我正在使用multer,我不知道如何使用multer,我只是按照文档进行了操作,但是当我试图创建一个带有配置文件图片的用户时,它显示了一个错误TypeError:无法读取未定义的属性“filename”。我使用MongoDB,express.js作为后端 这是我的密码 模型(user.js) 控制器(auth.js) 路由器(auth.js) index.server.js const express = require('express'); cons
TypeError:无法读取未定义的属性“filename”。我使用MongoDB,express.js作为后端
这是我的密码
模型(user.js)
控制器(auth.js)
路由器(auth.js)
index.server.js
const express = require('express');
const mongoose = require('mongoose');
const env = require('dotenv');
const cors = require('cors');
const app = express();
env.config();
// connecting to mongoose database
mongoose.connect(process.env.DATABASE,
{
useNewUrlParser:true,
useUnifiedTopology:true,
useCreateIndex: true,
useFindAndModify: false
}).then(() => {
console.log('database connected successfully')
}).catch((err) => {
console.log(err)
});
// routes
const authRoutes = require('./Home_Search_Client/routes/auth');
// middlewares
app.use(cors());
app.use(express.json());
app.use('/api', authRoutes);
// PORT NUMBER
app.listen(process.env.PORT, () => {
console.log(`server is running at port: ${process.env.PORT}`)
});
前端(反应,重发)
操作(user.action.js)
reducer(user.reducer.js)
容器(Signup.js)
import React,{useffect,useState}来自“React”
从“react redux”导入{useDispatch,useSelector}
从“react bootstrap”导入{按钮、列、容器、窗体、行}
从“../../Components/Layout”导入布局
从“../../Components/UI/Input”导入输入
从“../../actions”导入{signup}
从'react router dom'导入{Redirect};
常量注册=(道具)=>{
const[firstName,setFirstName]=useState(“”);
const[lastName,setLastName]=useState(“”);
const[email,setEmail]=useState(“”);
const[password,setPassword]=useState(“”);
const[profilePicture,setProfilePicture]=useState(“”);
const auth=useSelector((state)=>state.auth)
const user=useSelector((state)=>state.user)
const dispatch=usedpatch();
useffect(()=>{
如果(!user.loading){
setFirstName(“”);
setLastName(“”);
setEmail(“”);
设置密码(“”);
setProfilePicture(“”)
}
},[user.load]);
const userSignup=(e)=>{
e、 预防默认值();
常量用户={
名字,
姓,
电子邮件,
密码,
剖面图
};
发送(注册(用户));
console.log(用户)
};
如果(身份验证){
返回
}
if(用户加载){
返回加载
}
const handleProfilePicture=(e)=>{
setProfilePicture(e.target.files[0]);
}
返回(
{user.message}
setFirstName(e.target.value)}
/>
setLastName(e.target.value)}
/>
setEmail(e.target.value)}
/>
setPassword(e.target.value)}
/>
提交
)
}
导出默认注册
要从前端发送文件和其他数据,您需要使用。使用用户
对象和axios,我会这样做:
const formData=new formData();
//将'user'对象的所有属性附加到表单
for(对象项(用户)的常量[键,值]){
formData.append(键、值);
}
const response=wait axios.post('/signup',formData{
标题:{
//Multer只解析“多部分/表单数据”请求
“内容类型”:“多部分/表单数据”,
},
});
我一眼就看不出有什么错。您如何在前端发送请求?谢谢您的回复。我正在使用Axios。我还添加了一个前端,您可以查看@马克西莫洛夫。
const User = require('../models/user');
const bcrypt = require('bcrypt');
const shortid = require('shortid');
exports.signup = async (req, res) => {
User.findOne({ email: req.body.email }).exec(async (error, user) => {
if (error) return res.status(400).json({ error })
if (user)
return res.status(400).json({
message: "User already registered",
});
const { firstName, lastName, email, password } = req.body;
const hash_password = await bcrypt.hash(password, 10);
const profilePicture = req.file.filename
const userSignUp = {
firstName,
lastName,
email,
hash_password,
profilePicture: profilePicture,
username: shortid.generate(),
}
const _user = new User(userSignUp);
_user.save((error, data) => {
if (error) {
return res.status(400).json({
message: error,
});
}
if (data) {
return res.status(201).json({
message: "user created Successfully..!",
});
}
});
});
};
const express = require('express');
const { signup, signin, signout } = require('../controller/auth');
const { validateSignupRequest, isRequestValidated, validateSigninRequest } = require('../../validators/auth');
const router = express.Router();
const path = require('path');
const multer = require('multer');
router.use(express.static(__dirname+ '../../uploads'));
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, '../../uploads')
},
filename: (req,file, cb) => {
cb(null, file.filename + "_" + Date.now() + path.extname(file.originalname));
}
});
const upload = multer({ storage: storage }).single('profilePicture');
router.post('/signup', validateSignupRequest,isRequestValidated,upload,signup);
module.exports = router
const express = require('express');
const mongoose = require('mongoose');
const env = require('dotenv');
const cors = require('cors');
const app = express();
env.config();
// connecting to mongoose database
mongoose.connect(process.env.DATABASE,
{
useNewUrlParser:true,
useUnifiedTopology:true,
useCreateIndex: true,
useFindAndModify: false
}).then(() => {
console.log('database connected successfully')
}).catch((err) => {
console.log(err)
});
// routes
const authRoutes = require('./Home_Search_Client/routes/auth');
// middlewares
app.use(cors());
app.use(express.json());
app.use('/api', authRoutes);
// PORT NUMBER
app.listen(process.env.PORT, () => {
console.log(`server is running at port: ${process.env.PORT}`)
});
import axios from '../helpers/axios';
import { userContants } from './constants';
export const signup = (user) => {
console.log(user)
return async (dispatch) => {
dispatch({ type: userContants.USER_REGISTER_REQUEST });
const res = await axios.post(`/signup`, {
...user
});
if (res.status === 201) {
const { message } = res.data;
dispatch({
type: userContants.USER_REGISTER_SUCCESS,
payload: { message }
});
} else {
if (res.status === 400) {
dispatch({
type: userContants.USER_REGISTER_FAILURE,
payload: { error: res.data.error }
});
}
}
}
};
import { userContants } from "../actions/constants"
const initState = {
error: null,
message: '',
loading: false
}
export default (state = initState, action) => {
switch (action.type) {
case userContants.USER_REGISTER_REQUEST:
state = {
...state,
loading: true
}
break;
case userContants.USER_REGISTER_SUCCESS:
state = {
...state,
loading: false,
message: action.payload.message
}
break;
case userContants.USER_REGISTER_FAILURE:
state = {
...state,
loading: false,
error: action.payload.error
}
break;
}
return state;
}
import React, { useEffect, useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { Button, Col, Container, Form, Row } from 'react-bootstrap'
import Layout from '../../Components/Layout'
import Input from '../../Components/UI/Input'
import { signup } from '../../actions'
import { Redirect } from 'react-router-dom';
const Signup = (props) => {
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [profilePicture, setProfilePicture] = useState('');
const auth = useSelector((state) => state.auth)
const user = useSelector((state) => state.user)
const dispatch = useDispatch();
useEffect(() => {
if(!user.loading){
setFirstName('');
setLastName('');
setEmail('');
setPassword('');
setProfilePicture('')
}
}, [user.loading]);
const userSignup = (e) => {
e.preventDefault();
const user = {
firstName,
lastName,
email,
password,
profilePicture
};
dispatch(signup(user));
console.log(user)
};
if(auth.authenticate) {
return <Redirect to={'/'} />
}
if(user.loading) {
return <p>Loading...</p>
}
const handleProfilePicture = (e) => {
setProfilePicture(e.target.files[0]);
}
return (
<Layout>
<Container>
{user.message}
<Row>
<Col md={{ span:6, offset:3 }}>
<Form onSubmit={userSignup}>
<Row>
<Col md = {6}>
<Input
label = 'First Name'
placeholder='First Name'
value= {firstName}
type='text'
onChange={(e) => setFirstName(e.target.value)}
/>
</Col>
<Col md = {6}>
<Input
label = 'Last Name'
placeholder='Last Name'
value= {lastName}
type='text'
onChange={(e) => setLastName(e.target.value)}
/>
</Col>
</Row>
<Input
label='Email'
placeholder='Email'
value={email}
type='email'
onChange={(e) => setEmail(e.target.value)}
/>
<Input
label='Password'
placeholder='Password'
value={password}
type='password'
onChange={(e) => setPassword(e.target.value)}
/>
<input type="file" name= 'profilePicture' onChange={handleProfilePicture} />
<Button variant='primary' type='submit' >
Submit
</Button>
</Form>
</Col>
</Row>
</Container>
</Layout>
)
}
export default Signup