I want to add two collections with one action.(我想用一个动作添加两个集合。)
First one is file using multer and gridfs-stream and second is just literal with properties based on file.(第一个是使用multer和gridfs-stream的文件,第二个只是具有基于文件属性的文字。) That what I achieved: 1)literal based on file and 2)file uploaded .(我实现的目标: 1)基于文件的文字和2)上传的文件 。) In 1)(literal) this fileID property is just the same as _id of 2)(file) and src in 1) is just filename from 2) concatenated with some path.(在1)(字面量)中,此fileID属性与2)(文件)的_id相同,并且1)中的src只是2)中的文件名,并带有一些路径。) And here I have to problems.(在这里,我必须解决问题。) First is that this literal should have more properties, but I have problem with adding them.(首先,此文字应具有更多属性,但是添加它们时遇到问题。) Here's the model(I think that there's isn't any problem, but it contain all props needed):(这是模型(我认为没有任何问题,但其中包含所有需要的道具):)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
// Create Schema
const FileSchema = new Schema({
fileID: {
type: Schema.Types.ObjectId
},
src: {
type: String,
},
altText: {
type: String,
},
caption: {
type: String,
},
});
module.exports = File = mongoose.model('file', FileSchema);
The most important GET/POST routes(and also DELETE routes for second problem):(最重要的GET / POST路由(以及第二个问题的DELETE路由):)
router.get('/', (req, res) => {
File.find()
.sort({ date: -1 })
.then(files => res.json(files))
});
// @route POST /upload
// @desc Uploads file to DB
router.post('/', upload.single('file'), auth, (req, res) => {
const newFile = new File({
fileID: req.file.id,
src: 'api/files/image/' + req.file.filename,
altText: 'No image',
caption: req.body.caption
})
newFile.save()
});
// @route GET /files
// @desc Display all files in JSON
router.get('/', (req, res) => {
File.find()
.sort({ date: -1 })
.then(files => res.json(files))
});
// @route GET /files/:filename
// @desc Display single file object
router.get('/:filename', (req, res) => {
gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
// Check if file
if (!file || file.length === 0) {
return res.status(404).json({
err: 'No file exists'
});
}
// File exists
return res.json(file);
});
});
// @route DELETE /files/:id
// @desc Delete file
router.delete('/:id', auth, (req, res) => {
gfs.remove({ _id: req.params.id, root: 'files' }, (err, gridStore) => {
if (err) {
return res.status(404).json({ err: err });
}
});
File.findById(req.body.fileID)
.then(file => file.remove().then(() => res.json({ success: true })))
.catch(err => res.status(404).json({ success: false }));
});
and my React component most important fragments:(和我的React组件最重要的片段:)
const SliderModal = ({ isAuthenticated, addFile }) => {
const [modal, setModal] = useState(false);
const [file, setFile] = useState([]);
const [slideData, setSlideData] = useState({
fileID: '',
src: '',
altText: '',
caption: '',
})
const toggle = () => {
setModal(!modal);
};
const onChange = e => {
setFile(e.target.files[0]);
setSlideData({
...slideData,
[e.target.name]: e.target.value
});
};
const onSubmit = e => {
e.preventDefault();
const newFile = new FormData();
newFile.append('file', file);
// const { src, altText, caption, fileID } = slideData;
// const newSlide = {
// fileID,
// src,
// altText,
// caption
// }
// Add file via addItem action
addFile(newFile);
// addFile(newSlide);
// Close modal
toggle();
}
and next part(with use of reactstrap):(下一部分(使用reactstrap):)
<Form onSubmit={onSubmit}>
<FormGroup>
{/* <Label for="caption">Caption</Label>
<Input
type="text"
name="caption"
id="caption"
placeholder="Caption"
className="mb-3"
onChange={onChange}
/> */}
<Label for="file">File</Label>
<Input
type="file"
name="name"
id="file"
placeholder="Add file"
onChange={onChange}
/>
<Button
color="dark"
style={{ marginTop: '2rem' }}
block>
Add File
</Button>
</FormGroup>
</Form>
in which, when I uncomment I have the text input in my modal in which, when I wrote anything I'm getting error: Error while inputting text The second problem is connected with deleting files.(其中,当我取消注释时,我在模态中输入了文本,当我编写任何内容时,我遇到了错误: 输入文本时出错第二个问题与删除文件有关。)
At this moment I'm able to delete only one of items(literal or file) from database.(目前,我只能从数据库中删除一项(文字或文件)。) Here's DELETE route again: // @route DELETE /files/:id // @desc Delete file router.delete('/:id', auth, (req, res) => { gfs.remove({ _id: req.params.id, root: 'files' }, (err, gridStore) => { if (err) { return res.status(404).json({ err: err }); } }); File.findById(req.body.fileID) .then(file => file.remove().then(() => res.json({ success: true }))) .catch(err => res.status(404).json({ success: false })); });(这里再次是删除路由:// @route DELETE / files /:id // @desc删除文件router.delete('/:id',auth,(req,res)=> {gfs.remove({_id:req。 params.id,root:'files'},(err,gridStore)=> {如果(err){返回res.status(404).json({err:err});}})); File.findById(req .body.fileID).then(file => file.remove()。then(()=> res.json({success:true})))).catch(err => res.status(404).json( {成功:否}));});)
Okay, I see that File.findById isn't good function, but the problem is that I want to delete them simultaneously.(好的,我看到File.findById不是一个好的函数,但是问题是我想同时删除它们。)
That's why in this literal I concluded that fileID property, but I'm really confused about it and can't find a solution.(这就是为什么我用这个字面量得出了fileID属性的原因,但是我对此感到非常困惑,无法找到解决方案。) My idea was to search by this fileID property both and then delete them.(我的想法是同时通过fileID属性进行搜索,然后将其删除。) Here's react function to delete only file(don't look at that is authenticated, that's just that I can delete file only when I'm logged in my app):(这是只删除文件的react函数(不要看已通过身份验证,这就是我只有在登录应用后才能删除文件):)
{files.map(({ fileID}) => (
< CSSTransition key={fileID} timeout={500} classNames="fade" >
<ListGroupItem>
{isAuthenticated ?
<Button
className="remove-btn"
color="danger"
size="sm"
onClick={onDeleteClick.bind(this, fileID)}
>×
</Button> : null}
</ListGroupItem>
</CSSTransition>
))}
ask by Victor translate from so