My problem is that I receive a validation error on my server when trying to update my user and product collection in mongodb using formik on my front end.
I add a new product as logged in user. All of the authentication is working with JWT token.
"ValidationError: Product validation failed: title: Path title
is required., description: Path description
is required., price: Path price
is required., location: Path location
is required., condition: Path condition
is required., category: Path category
is required."
I've looked everywhere on stack of, and tried everything for 30+ hours. If anyone could help, I'd appreciate it. I feel bad for asking this novice question, but I've been struggling.
Here is my front end code using formik and axios :
const schema = yup.object().shape({
title: yup.string().required('Title is required'),
description: yup.string().required('Description is required'),
price: yup.number().required('Price is required').positive('Price must be a positive number'),
location: yup.string().required('Location is required'),
condition: yup.string().required('Condition is required'),
category: yup.string().required('Category is required'),
});
const addProductFormik = useFormik({
initialValues: {
title: "",
description: "",
price: "",
location: "",
condition: "",
category: "",
},
validationSchema: schema,
onSubmit: async (values) =\> {
try {
const formData = new FormData();
formData.append('title', values.title);
formData.append('description', values.description);
formData.append('price', values.price);
formData.append('location', values.location);
formData.append('condition', values.condition);
formData.append('category', values.category);
console.log(formData.get('title'));
console.log(formData.get('price'));
const url = `http://localhost:3005/product/${user._id}/add-product`;
const config = {
headers: { Authorization: 'Bearer ' + token }
};
console.log(config);
const response = await axios.post(url, formData, config);
console.log(response);
const newProduct = response.data.product;
console.log(newProduct);
// dispatch(addProduct(newProduct));
} catch (error) {
console.log(error)
console.error(error);
}
},
});
Here is my controller function to update my mongo database :
export const createProduct = async (req, res, next) => {
try {
const id = req.params.userId;
const user = await User.findById(id);
if (!user) {
return res.status(404).json({ message: "User not found" });
}
console.log('user was found')
const createdProduct = new Product({
title: req.body.title,
description: req.body.description,
price: req.body.price,
location: req.body.location,
condition: req.body.condition,
category: req.body.category,
});
console.log(createdProduct);
console.log('product was created')
console.log(createdProduct._id);
try {
createdProduct.save();
user.products.push(createdProduct._id);
Product.insertMany(createdProduct);
// JWT token signing
const token = jwt.sign({ userId: user.id }, 'supersecretkey', { expiresIn: '1h' });
res.status(201).json({ product: createdProduct, token });
} catch (err) {
const error = new HttpError(
'Creating product failed, please try again.',
500
);
return next(error);
}
console.log('controller function works!');
} catch (error) {
console.error(error)
res.status(404).json({ message: error.message });
}
};
Here is my Product Schema :
import mongoose from "mongoose";
const Schema = mongoose.Schema;
const ProductSchema = new Schema({
title: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: {
type: Number,
required: true,
},
location: {
type: String,
required: true,
},
condition: {
type: String,
required: true,
},
category: {
type: String,
required: true,
enum: ["Cars", "Electronics", "Clothing", "Furniture", "Other"],
},
seller: {
type: Schema.Types.ObjectId,
ref: "User",
},
createdAt: {
type: Date,
default: Date.now,
},
});
const Product = mongoose.model("Product", ProductSchema);
export default Product;
Here is my User Schema :
import mongoose from "mongoose";
const Schema = mongoose.Schema;
const UserSchema = new Schema({
firstName: {
type: String,
required: true,
min: 2,
max: 50,
},
lastName: {
type: String,
required: true,
min: 2,
max: 50,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
location: {
type: String,
required: true,
},
products: [
{
type: Schema.Types.ObjectId,
ref: "Product",
},
],
createdAt: {
type: Date,
default: Date.now,
},
});
const User = mongoose.model("User", UserSchema);
export default User
Now when I submit the form, there is no error on the front end. I get a 201 response and when I console log the newProduct in the addProductFormik, this is what it says :
_id: '63f27485ed59ed8c6fdff654', createdAt: '2023-02-19T19:12:05.981Z'} createdAt: "2023-02-19T19:12:05.981Z" _id: "63f27485ed59ed8c6fdff654"
On the back end, i get this error : "ValidationError: Product validation failed: title: Path title
is required., description: Path description
is required., price: Path price
is required., location: Path location
is required., condition: Path condition
is required., category: Path category
is required."
Now if you look at the console logs made in the controller function, these are the console logs that are logged on the server,
user was found
{
_id: new ObjectId("63f27485ed59ed8c6fdff654"),
createdAt: 2023-02-19T19:12:05.981Z
}
product was created
new ObjectId("63f27485ed59ed8c6fdff654")
controller function works!
So within my controller function, it finds the user in params, the createdProduct is only shown as a new ObjectId and not with all of its fields (title, description, price, etc). Somehow, it makes it through all the try blocks and console logs the controller function works. But my products collection and user collection (user.products) is not updated and I get that validation error.