我有以下内容
import React,{ Component } from "react";
import axios from "axios";
import swal from "sweetalert";
import AuthService from "../../Auth/AuthService";
import withAuth from "../../Auth/withAuth";
const Auth = new AuthService();
class Create extends Component {
constructor() {
super();
this.state = {
title: "",description: "",reference: "",images: [],price: "",year: "",categoryName: "",categorys: [],sold: false,titleErr: "",descriptionErr: "",referenceErr: "",imagesErr: "",priceErr: "",yearErr: "",categoryErr: ""
};
}
validate = () => {
let titleErr = "";
let descriptionErr = "";
let referenceErr = "";
let imagesErr = "";
let priceErr = "";
let yearErr = "";
let categoryNameErr = "";
// Title validation
if (!this.state.title) {
titleErr = "Please enter a title";
}
// Description validation
if (!this.state.description) {
descriptionErr = "Please enter a description";
}
// Reference validation
if (!this.state.reference) {
referenceErr = "Please enter a reference";
}
// Images validation
if (!this.state.images.length) {
imagesErr = "You must have at least one image";
}
// Price validation
if (!this.state.price) {
priceErr = "Please enter a price";
}
// Year validation
if (!this.state.year) {
yearErr = "Please enter a year";
}
// Category validation
if (!this.state.categoryName) {
categoryNameErr = "Please enter a category";
}
// Render validations
if (
titleErr ||
descriptionErr ||
referenceErr ||
imagesErr ||
priceErr ||
yearErr ||
categoryNameErr
) {
this.setState({
titleErr,descriptionErr,referenceErr,imagesErr,priceErr,yearErr,categoryNameErr
});
return false;
}
return true;
};
componentDidmount() {
axios
.get("/api/category")
.then(res => this.setState({ categorys: res.data }))
.catch(error => {
console.log(error);
});
}
onTitleChange(event) {
this.setState({ title: event.target.value });
}
onDescriptionChange(event) {
this.setState({ description: event.target.value });
}
onReferenceChange(event) {
this.setState({ reference: event.target.value });
}
onImagesChange(event) {
this.setState({ images: event.target.value });
}
onPriceChange(event) {
this.setState({ price: event.target.value });
}
onYearChange(event) {
this.setState({ year: event.target.value });
}
onCategoryNameChange(event) {
this.setState({ categoryName: event.target.value });
}
onSoldChange(event) {
this.setState({ sold: event.target.value });
}
onSubmit = e => {
e.preventDefault();
const isValid = this.validate();
const {
title,description,reference,images,price,year,categoryName,sold
} = this.state;
let config = {
headers: {
"Content-Type": "multipart/form-data",Authorization: "bearer " + Auth.getToken()
}
};
var formData = new FormData();
formData.append("title",title);
formData.append("description",description);
formData.append("reference",reference);
formData.append("price",price);
formData.append("images",images);
formData.append("year",year);
formData.append("categoryName",categoryName);
formData.append("sold",sold);
for (let i = 0; i < images.length; i++) {
formData.append("images",images[i]);
}
if (isValid) {
axios
.post("/api/collections/create",formData,config)
.then(function(response) {
swal({
title: "Success",text: "You have created a collection",icon: "success",button: "OK"
});
this.props.history.push("/dashboard");
console.log(response);
})
.catch(function(response) {
swal({
title: "Error",text: `${response}`,icon: "error",button: "Try again"
});
});
}
};
render() {
const {
title,sold
} = this.state;
return (
<>
<div classname='block md:flex md:flex-column h-full'>
<div classname='p-12 w-full text-center text-gray-800'>
<h1 classname='title mb-10'>Create a collection</h1>
<form
classname='w-full m-auto max-w-lg'
encType='multipart/form-data'
onSubmit={this.onSubmit}
>
<div classname='flex flex-wrap mb-4'>
<label htmlFor='title'>Title:</label>
<input
type='text'
name='title'
value={title}
onChange={this.onTitleChange.bind(this)}
placeholder='Title'
/>
<p classname='mt-2 text-red-500 text-xs'>
{this.state.titleErr}
</p>
</div>
<div classname='flex flex-wrap'>
<label htmlFor='description'>Description:</label>
<textarea
type='text'
name='description'
classname='h-64'
value={description}
onChange={this.onDescriptionChange.bind(this)}
placeholder='Content'
></textarea>
<p classname='mb-4 text-red-500 text-xs'>
{this.state.descriptionErr}
</p>
</div>
<div classname='flex flex-wrap mb-4'>
<label htmlFor='reference'>Reference:</label>
<input
type='text'
name='reference'
value={reference}
onChange={this.onReferenceChange.bind(this)}
placeholder='reference'
/>
<p classname='mt-2 text-red-500 text-xs'>
{this.state.referenceErr}
</p>
</div>
<div classname='flex flex-wrap mb-4'>
<label htmlFor='images'>images:</label>
<input
type='file'
multiple
name='images'
value={images}
accept='image/*'
onChange={this.onImagesChange.bind(this)}
></input>
<p classname='mt-2 text-red-500 text-xs'>
{this.state.imagesErr}
</p>
</div>
<div classname='flex flex-wrap mb-4'>
<label htmlFor='price'>Price:</label>
<input
type='number'
name='price'
value={price}
onChange={this.onPriceChange.bind(this)}
placeholder='price'
/>
<p classname='mt-2 text-red-500 text-xs'>
{this.state.priceErr}
</p>
</div>
<div classname='flex flex-wrap mb-4'>
<label htmlFor='year'>Year:</label>
<input
type='number'
name='year'
value={year}
onChange={this.onYearChange.bind(this)}
placeholder='Year'
/>
<p classname='mt-2 text-red-500 text-xs'>
{this.state.yearErr}
</p>
</div>
<div classname='flex flex-col mb-4'>
<label htmlFor='categoryName'>Category</label>
<div classname='relative'>
<select
name='categoryName'
value={categoryName}
onChange={this.onCategoryNameChange.bind(this)}
>
<option>N/A</option>
{this.state.categorys.map(category => (
<option key={category._id} value={category.name}>
{category.name}
</option>
))}
</select>
<div classname='pointer-events-none absolute inset-y-0 right-0 flex items-center px-2'>
<svg
classname='fill-current h-4 w-4'
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 20 20'
>
<path d='M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z' />
</svg>
</div>
</div>
</div>
<div classname='flex flex-col mb-2'>
<label htmlFor='sold'>Sold?</label>
<div classname='relative'>
<select
name='sold'
value={sold}
onChange={this.onSoldChange.bind(this)}
>
<option value='false'>No</option>
<option value='true'>Yes</option>
</select>
<div classname='pointer-events-none absolute inset-y-0 right-0 flex items-center px-2'>
<svg
classname='fill-current h-4 w-4'
xmlns='http://www.w3.org/2000/svg'
viewBox='0 0 20 20'
>
<path d='M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z' />
</svg>
</div>
</div>
</div>
<div classname='flex'>
<button type='submit' classname='btn w-full'>
Submit
</button>
</div>
</form>
</div>
</div>
</>
);
}
}
export default withAuth(Create);
我正在尝试将所有图像保存为数组,以便可以保存s3文件名和位置。
就快递而言,我有以下内容
/* POST create a collection */
module.exports.createCollection = [
...validations,(req,res) => {
// Get validation errors from the request
const errors = validationResult(req);
// Return the errors
if (!errors.isEmpty()) {
return res.status(422).json({ error: errors.array() });
}
Collections.findOne({ _id: req.body.id })
.then(function(collection) {
return Collections.create({
title: req.body.title,description: req.body.description,reference: req.body.reference,images: req.files.map(({ originalname,location }) => ({
originalname,location
})),price: req.body.price,year: req.body.year,categoryName: req.body.categoryName,sold: req.body.sold
});
})
.then(
function(collection) {
res.status(201).json(collection);
console.log("Successfully uploaded " + req.files.length + " files!");
},function(error) {
console.error(error);
res.status(500).send(error);
}
);
}
];
当我在邮递员中对此进行测试时,该请求有效并且得到了预期的结果,但是反应并不多。
我得到Error: Request failed with status code 422
的错误。
这是邮递员的预期结果。
在邮递员中创建记录时,图像正在上传,因此这里的问题似乎与React有关。
我该如何进行反应?