I have a multipart form that I am nearly finished working on that is still not posting to my backend database. Could this be to do with the fact that I am not parsing my two ID fields as ints correctly?
The two text fields and file field look like they are being sent in the request correctly. Is the random pink/blue/black/red symbols the image being sent to the backend? Should my two ID int fields also be showing here as they are on the same form?
The method I have for my Argument 1 is not an object seems to be related to the diveSpotForm line of my handle submit method. Am I passing the form data to the action correctly? I think I might have over complicated the method not posting straight from the form component.
form component
const [spot, setSpot] = useState({
diveLocation: "",
diveRegionID: parseInt(``),
diveTypeID: parseInt(``),
diveSpotDescription: "",
diveSpotPhotos: "",
error: ''
});
// all onChange functions do the exact same thing, so you only need one
// pass to a component like onChange={handleChange('typeID')}
const handleChange = (property) => (e) => {
setSpot({
// override the changed property and keep the rest
...spot,
[property]: e.target.value,
});
}
// get access to dispatch
const dispatch = useDispatch();
// useEffect with an empty dependency array is the same as componentDidMount
useEffect(() => {
dispatch(requireFieldData());
}, []);
const handleSubmitDiveSpot = () => {
const diveSpotForm = new FormData(document.querySelector("diveSpotForm"))
console.log('diveSpotForm', diveSpotForm);
const diveSpot = {
diveLocation: spot.diveLocation || undefined,
diveRegionID: spot.diveRegionID || undefined,
diveSpotTypeID: spot.diveSpotTypeID || undefined,
diveSpotDescription: spot.diveSpotDescription || undefined,
diveSpotPhotos: spot.diveSpotPhotos || undefined
}
// do some stuff with the form
createDiveSpot(diveSpot).then((data) => {
const newSpot = data.error
? {...spot, error: data.error}
: {...spot, error: '', open: true};
setSpot(newSpot);
dispatch(addDiveSpot(newSpot));
})
}
const classes = useStyles;
return (
<form className="diveSpotForm" method="POST" encType="multipart/form-data" onSubmit={handleSubmitDiveSpot}>
<>
<Grid container spacing={3}
direction="row"
justify="center"
alignItems="center">
<Grid item xs={4}>
<FormControl className={classes.formControl}>
<PopulateDropdown
dataList={diveTypeList}
titleProperty={"diveType"} // option label property
valueProperty={"diveTypeID"} // option value property
name="diveType"
placeholder="Dive Type"
label="Select Dive Type"
value={spot.diveTypeID}
onChange={handleChangeInt(parseInt("diveTypeID"))}/>
</FormControl>
</Grid>
<br />
........
<br />
<Grid item xs={10}>
<FormControl fullWidth className={classes.margin}>
<TextField
label="Description"
name="diveSpotDescription"
value={spot.diveSpotDescription}
onChange={handleChange("diveSpotDescription")}
multiline
rowsMax={6}/>
</FormControl>
</Grid>
<br />
<Grid item xs={12}>
<FormControl fullWidth className={classes.margin}>
<label for="photos">Photo Upload</label>
<input
type="file"
name="photo"
value={spot.diveSpotPhotos}
onChange={handleChange("diveSpotPhotos")}/>
</FormControl>
</Grid>
<br />
<Grid item xs={3}>
<Button variant="primary" type="submit">
Submit</Button>
<br />
</Grid>
</Grid>
</>
</form>
action
export const createDiveSpot = async (diveSpot) => {
try {
let response = await fetch('http://localhost:5002/api/divespot/createdivespot', {
method: 'POST',
headers: {
"Content-Type":"multipart/form-data"
},
body: new FormData(diveSpot)
})
return await response.json()
} catch(err) {
console.log(err)
}
}
backend
exports.createDiveSpot = async (req, res) => {
const fileNameWithExtension = `${req.file.filename}-${req.file.originalname}`
const newPath = `./assets/diveSpot/${fileNameWithExtension}`
fs.rename(req.file.path, newPath, function (err) {
if (err) {
console.log(err)
res.send(500)
}
diveSpot.create({
diveLocation: req.body.diveLocation,
diveRegionID: req.body.diveRegionID,
diveSpotTypeID: req.body.diveLocation,
diveSpotDescription: req.body.diveSpotDescription,
photos: fileNameWithExtension,
})
.catch((err) => {
res.status(500).send({
message: err.message || 'Some error occurred while creating the post.',
})
})
}
)}
route
app.post('/api/divespot/createdivespot', upload.single("diveSpotPhotos"), controller.createDiveSpot);
update
I have also tried the below handleSubmit method and it is still showing the same two argument 1 is not an object errors. As there are two of them it looks like it could be the two id fields ( which are also not appearing on the payload request in the console).
function diveSpotForm(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const formData = new FormData();
formData.append("diveLocation", spot.diveLocation);
formData.append("diveRegionID", spot.diveRegionID);
formData.append("diveSpotTypeID", spot.diveSpotTypeID);
formData.append("diveSpotDescription", spot.diveSpotDescription);
formData.append("photos", file);
axios.post("http://localhost:5002/api/divespot/createdivespot", formData);
}


