Reputation: 6473
I'm trying to upload images. It's reaching the backend, but the request body and req.image
are coming out empty.
I have the submission:
const handleSubmit = async () => {
try {
const data = createFormData();
console.log(data); // prints the correct request object
const response = await axios.post(
`http://${GATEWAY}:5000/api/uploads/single`,
JSON.stringify(data)
);
alert("Upload success!");
console.log("response.data", response.data);
} catch (err) {
console.log("err caught --> ", err);
}
};
const createFormData = () => {
const data = new FormData();
data.append("title", title); // coming from
data.append("body", body); // react hooks state (useState)
data.append("image", {
height: image.height,
width: image.width,
type: image.type,
uri:
Platform.OS === "android" ? image.uri : image.uri.replace("file:/", "")
});
return data;
};
My endpoint:
const express = require("express");
const multer = require("multer");
const bodyParser = require("body-parser");
express().use(bodyParser.json());
const router = express.Router();
// middleware
const auth = require("../../middleware/auth");
const storage = multer.diskStorage({
destination(req, file, callback) {
callback(null, "./images");
},
filename(req, file, callback) {
callback(null, `${file.fieldname}_${Date.now()}_${file.originalname}`);
}
});
const upload = multer({ storage });
// @route POST api/uploads/single
// @desc Upload single image
// @access Private
router.post(
"/single",
// upload.array("photo", 3),
auth,
upload.single("image"),
(req, res) => {
console.log("req", req.body); // {}
console.log("req", req.image); // undefined
return res.status(200).json({
message: "Response from backend"
});
}
);
module.exports = router;
And my server.js
const express = require("express");
const connectDb = require("./config/db");
const app = express();
// connect to db
connectDb();
// Define routes (some omitted for brevity)
app.use("/api/uploads", require("./routes/api/uploads"));
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
For some reason, in the first snippet, if I do not stringify the data: FormData
object that is built from createFormData()
, my backend is never even reached.
I've tried so many things, and I'm not starting to think that maybe my backend isn't setup properly. The line where I'm doing express().use(bodyParser.json());
exists because I can't do app.use(bodyParser.json());
(or at least I think), because the app object is in the main server.js
file. I'm including other API routes in other files.
For example, my server.js
has these, amongst others:
// Define routes
app.use("/api/auth", require("./routes/api/auth"));
app.use("/api/users", require("./routes/api/users"));
app.use("/api/profile", require("./routes/api/profile"));
app.use("/api/uploads", require("./routes/api/uploads"));
And I was following this tutorial to use multer with react-native. A little lost at this point, not sure what I'm doing wrong.
Edit:
I'm making the request like this now,
const config = {
headers: {
"Content-Type": "multipart/form-data"
}
};
const response = await axios.post(
`http://${GATEWAY}:5000/api/uploads/single`,
data,
config
);
But It's failing with a
If I stringify it, it hits the backend but not in the way I need it to:
Edit:
I got it working by specifying the image type, as per the suggestion here
Upvotes: 0
Views: 889
Reputation: 1102
I used the following line to get images:-
concole.log(req.files);
Upvotes: 0
Reputation: 6473
Got it working by specifying the image type as per the suggestion here
Upvotes: 0
Reputation: 469
You're trying to access the file from req.image and req.body, but as mentioned in the https://www.npmjs.com/package/multer, you can access it from :
req.file
req.body will hold the text fields only, on the other hand, if you only uploaded a single file you can find it in req.file, but if you uploaded multiple files you will find them in req.files.
Upvotes: 0
Reputation: 111
I think this is because you are not setting your content-type to multipart/form-data. Try adding this to your request options:
const response = await axios.post(
`http://${GATEWAY}:5000/api/uploads/single`,
data,
headers: {
`Content-Type`: `multipart/form-data`
}
);
Because of multipart/form-data, do not stringify the data you are sending. Stringifying the data will cause it to only be read as text by the server but is expecting a file to be attached.
Upvotes: 1