4-17강의 거의다 듣다 게시물 포스트가 되지 않아 질문드려요
네트워크 창에서는 에러 500이라 뜨고, 터미널에서는 유저 이메일, 패스워드, 닉네임이 널이 되면 안된다 하는데
ValidationError [SequelizeValidationError]: notNull Violation: User.email cannot be null,
notNull Violation: User.nickname cannot be null,
notNull Violation: User.password cannot be null
at InstanceValidator._validate (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:78:13)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async InstanceValidator._validateAndRunHooks (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:111:7)
at async InstanceValidator.validate (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:93:12)
at async model.save (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\model.js:3890:7)
at async Function.create (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\model.js:2207:12)
at async C:\Users\com\vue강좌\복습\back\routes\post.js:32:21 {
errors: [
ValidationErrorItem {
message: 'User.email cannot be null',
type: 'notNull Violation',
path: 'email',
value: null,
origin: 'CORE',
instance: [User],
validatorKey: 'is_null',
validatorName: null,
validatorArgs: []
},
ValidationErrorItem {
message: 'User.nickname cannot be null',
type: 'notNull Violation',
path: 'nickname',
value: null,
origin: 'CORE',
instance: [User],
validatorKey: 'is_null',
validatorName: null,
validatorArgs: []
},
ValidationErrorItem {
message: 'User.password cannot be null',
type: 'notNull Violation',
path: 'password',
value: null,
origin: 'CORE',
instance: [User],
validatorKey: 'is_null',
validatorName: null,
validatorArgs: []
}
]
}
SequelizeValidationError: notNull Violation: User.email cannot be null,
notNull Violation: User.nickname cannot be null,
notNull Violation: User.password cannot be null
at InstanceValidator._validate (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:78:13)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async InstanceValidator._validateAndRunHooks (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:111:7)
at async InstanceValidator.validate (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:93:12)
at async model.save (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\model.js:3890:7)
at async Function.create (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\model.js:2207:12)
at async C:\Users\com\vue강좌\복습\back\routes\post.js:32:21
POST /post 500 21.201 ms - 1150
구글링도 해보고 찾아 봤는데 방법이 안나와 질문 드립니다.
유저 이메일 등이 잘못 설정이 된거면 도대체 어디에서 잘못된건지 만진적이 없는거 같은데 ㅜ 도와주시면 감사하겠습니다
참고로 코딩페이지 보내드리겠습니다
routes/post.js(백엔드)
const express = require('express')
const multer = require('multer')
const path = require('path')
const db = require('../models')
const { isLogedIn, isNotLogedIn } = require('./middlewares')
const router = express.Router()
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) {
done(null, 'uploads');
},
filename(req, file, done) {
const ext = path.extname(file.originalname)
const basename = path.basename(file.originalname, ext)
done(null, basename + Date.now() + ext)
}
}),
limit: { fileSize: 20 * 1024 * 1024}
})
router.post('/images', isLogedIn, upload.array('image'), (req, res) => {
console.log(req.files);
res.json(req.files.map(v => v.filename));
})
router.post('/', isLogedIn, async (req, res, next) => {
try {
const hashtags = req.body.content.match(/#[^\s#]+/g);
const newPost = await db.Post.create({
content: req.body.content,
UserId: req.user.id,
});
if (hashtags) {
const result = await Promise.all(hashtags.map(tag => db.Hashtag.findOrCreate({
where: { name: tag.slice(1).toLowerCase() },
})));
await newPost.addHashtags(result.map(r => r[0]));
}
const fullPost = await db.Post.findOne({
where: { id: newPost.id },
include: [{
model: db.User,
attributes: ['id', 'nickname'],
}],
});
return res.json(fullPost);
} catch (err) {
console.error(err);
next(err);
}
});
module.exports = router
PostForm.vue(프론트엔드)
<template>
<v-card style="margin-bottom: 20px">
<v-container>
<v-form ref="form" v-model="valid" @submit.prevent="onSubmitForm">
<v-textarea
outlined
auto-grow
clearable
v-model="content"
label="어떤 신기한 일이 있었나요?"
:hide-details="hideDetails"
:success-messages="successMessages"
:success="success"
:rules="[v => !!v || '내용을 입력해라']"
@input="onChangeTextarea"
/>
<v-btn type="submit" color="green" absolute right>짹짹</v-btn>
<input ref="imageInput" type="file" multiple hidden @change ="onChangeImages">
<v-btn @click="onClickImageUpload" type="button">이미지 업로드</v-btn>
<div>
<div v-for="(p, i) in imagePaths" :key="p" style="display: inline-block">
<img :src="`http://localhost:3085/${p}`" :alt="p" style="width: 200px">
<div>
<button @click="onRemoveImage(i)" type="button">제거</button>
</div>
</div>
</div>
</v-form>
</v-container>
</v-card>
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {
valid: false,
hideDetails: false,
successMessages: '',
success: false,
content: '',
}
},
computed: {
...mapState('users', ['me']),
...mapState('posts', ['imagePaths'])
},
methods: {
onChangeTextarea(value) {
if(value.length) {
this.hideDetails = true;
this.success = false;
this.successMessages = '';
}
},
onSubmitForm() {
if(this.$refs.form.validate()) {
this.$store.dispatch('posts/add', {
content : this.content,
})
.then(() => {
this.content = '',
this.hideDetails = false;
this.success = true;
this.successMessages = '게시글 등록 성공';
})
.catch(() => {
})
}
},
onClickImageUpload() {
this.$refs.imageInput.click();
},
onChangeImages(e) {
console.log(e.target.files)
const imageFormData = new FormData();
[].forEach.call(e.target.files, (f) => {
imageFormData.append('image', f)
})
this.$store.dispatch('posts/uploadImages', imageFormData)
},
onRemoveImage(index) {
this.$store.commit('posts/removeImagePaths', index)
}
}
}
</script>
<style>
</style>
posts.js(프론트엔드)
export const state = () => ({
mainPosts: [],
hasMorePost: true,
imagePaths: []
})
const limit = 10;
const totalPosts = 51
export const mutations = {
addMainPosts(state, payload) {
state.mainPosts.unshift(payload);
state.imagePaths = [];
},
removeMainPosts(state, payload) {
const index = state.mainPosts.findIndex(v => v.id === payload.id);
state.mainPosts.splice(index, 1)
},
addComment(state, payload) {
const index = state.mainPosts.findIndex(v => v.id === payload.postId);
state.mainPosts[index].Comments.unshift(payload)
},
loadPosts(state, payload) {
const diff = totalPosts - state.mainPosts.length
const fakePosts = Array(diff > limit ? limit : diff).fill().map(v => ({
id: Math.random().toString(),
User: {
id: 1,
nickname: "Moon"
},
content: `hello infinite scrolling ${Math.random()}`,
Comments: [],
Img: [],
}))
state.mainPosts = state.mainPosts.concat(fakePosts)
state.hasMorePost = fakePosts.length === limit
},
concatImagePaths(state, payload) {
state.imagePaths = state.imagePaths.concat(payload)
},
removeImagePaths(state, payload) {
state.imagePaths.splice(payload, 1)
}
}
export const actions = {
add({commit, state}, payload) {
this.$axios.post('http://localhost:3085/post', {
content: payload.content,
imagePaths: state.imagePaths,
}, {
withCredentials: true
})
.then((res) => {
commit('addMainPosts', res.data)
})
.catch(() => {
})
},
remove({commit}, payload) {
commit('removeMainPosts', payload)
},
addComment({commit}, payload) {
commit('addComment', payload)
},
loadPosts({commit, state}, payload) {
if(state.hasMorePost) {
commit('loadPosts', payload)
}
},
uploadImages({ commit }, payload) {
this.$axios.post('http://localhost:3085/post/images', payload, {
withCredentials: true,
})
.then((res) => {
commit('concatImagePaths', res.data);
})
.catch(() => {
})
}
}
감사합니다!
저도 그런거 같아서 제로초님 코드 그대로 복사도 해보고 수정해봤는데 같은 오류가 뜨네요 ㅜㅜ
구글링도 해보고 하는데 도저히 프론트 어디서 잘못된지 감이 안오네요 ㅜ
프론트에서 잘못 전달하는거 같아서 PostForm이나 posts.js도 봤는데 제눈엔 이상이 없어 보이는데 무엇이 문제인지......