#StackBounty: #node.js #reactjs #express #redux #multipartform-data Multipart form component "cannot POST / divespotform" not…

Bounty: 50

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? (I have to figure out how to use parseINT properly). I am getting a NaN error for these.

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? I just want to store the url rather than save the image on my database (isn’t this base64?) I take it even if I am only storing the url in my database the image will always be sent to the backend so it will always be sent this way? Should I be splitting my different types of data in my action int/text/file in some way?

enter image description here

enter image description here

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 = () => {

        let diveSpot = new FormData()

        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 (

        // <AppBar title="Enter your dive details"></AppBar>
        <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={handleChange("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) => {
    try {
        console.log(req.diveSpot);

        // if (req.diveSpot == undefined) {
        //     return res.send(`You must select a file.`);
        // }

        diveSpot.create({
            diveLocation: req.diveSpot.diveLocation,
            diveRegionID: req.diveSpot.diveRegionID,
            diveSpotTypeID: req.diveSpot.diveSpotTypeID,
            diveSpotDescription: req.diveSpot.diveSpotDescription,
            diveSpotPhotos: fs.readFileSync(
                __basedir + "/assets/" + req.file.filename
            ),
        }).then((diveSpot) => {
            fs.writeFileSync(
                __basedir + "/assets/"
            );

            return res.send(`File has been uploaded.`);
        });
    } catch (error) {
        console.log(error);
        return res.send(`Error when trying upload images: ${error}`);
    }
};

route

app.post('/api/divespot/createdivespot', upload.single("diveSpotPhotos"), controller.createDiveSpot);


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.