I'm trying to send a file "image" with another post parameters using axios with react library, this is my original code which works very well sending one image or a file to the server.. in the server i'm using multer library to save the images:
submitFormImagen(e){
e.preventDefault();
const token = localStorage.getItem('auth-token');
const formData = new FormData();
formData.append('myImage',this.state.file);
const config = {
headers: {
'content-type': 'multipart/form-data',
'auth-token': token
}
};
axios.post("http://localhost:5000/api/user/upload",formData,config)
.then((response) => {
alert("The file is successfully uploaded");
console.log(response)
this.setState({imagen: response.data.imagen})
}).catch((error) => {
});
}
in this case: formData is necessary to multer library can save the image; this is my code from the server:
router.post('/upload', verificarToken, async function(req,res){
//imagen nombre: req.file.filename
console.log(req.body)
const url = req.protocol + '://' + req.get('host')
const _id = req.user._id
upload (req, res, async function(err) {
if(err) {
return res.end("Ocurrio un error al subir el archivo.");
}
const rutaimagen = url + "/uploads/" +req.file.filename
//Actualizar Imagen del usuario:
await User.findByIdAndUpdate(_id, {
imagen: rutaimagen
});
//res.end("Archivo subido correctamente!");
res.json({imagen: rutaimagen})
});
});
basically that's it now i'm trying to capture the request body to try to update the user image and his name and email..
this update does not work:
submitFormImagen(e){
e.preventDefault();
const token = localStorage.getItem('auth-token');
const formData = new FormData();
formData.append('myImage',this.state.file);
var post = {
myImage: this.state.file,
name: this.state.name,
email: this.state.email
}
const config = {
headers: {
'content-type': 'multipart/form-data',
'auth-token': token
}
};
axios.post("http://localhost:5000/api/user/upload",post,config)
.then((response) => {
alert("The file is successfully uploaded");
console.log(response)
this.setState({imagen: response.data.imagen})
}).catch((error) => {
});
}
Also I tryed:
formData.append('myImage',this.state.file);
var post = {
name: this.state.name,
email: this.state.email
}
formData.append('anotherdata',post);
const config = {
headers: {
'content-type': 'multipart/form-data',
'auth-token': token
}
};
axios.post("http://localhost:5000/api/user/upload",formData,config)
...
and now i'm trying to get the value of "anotherdata" inside the upload function from the server which is inside the upload route.. but I got:
[Object: null prototype] { anotherdata: '[object Object]' }
this is the code of the server:
router.post('/upload', verificarToken, async function(req,res){
//imagen nombre: req.file.filename
const url = req.protocol + '://' + req.get('host')
const _id = req.user._id
upload (req, res, async function(err) {
console.log(req.body) //<*********
if(err) {
return res.end("Ocurrio un error al subir el archivo.");
}
Related
I want to create an endpoint which should store file on server side as well as the some json data which should be received from same point is to be stored on mongodb.
I am using axios to send request from React App. Here is my Code.
const [companyFile, setCompanyFile] = useState(null);
const [company, setCompany] = useState({
name: "",
websiteUrl: "",
email: "",
companyLocation: "",
});
const AddCompany = async (e) => {
if (companyFile) {
e.preventDefault();
let formData = new FormData();
formData.append("company-file", companyFile);
formData.append("company", JSON.stringify(company));
axios({
method: "post",
url: `http://localhost:8080/company/add`,
data: formData,
withCredentials: true,
header: {
Accept: "application/json",
"Content-Type": "multipart/form-data",
},
}).then((res) => console.log(res.data));
} else {
console.log("file not selected!!!!");
}
};
Now I don't know how to check if it is coming to backend express server or not? Or if coming then how to retrive application/json data from request for further process.
My question is that if data is sent to backend express then how to process that data in backend (i.e. get json data to create an document in mongodb).
Here is my code for company/add
let upload = multer({
storage: multer.diskStorage({
destination: async (req, file, cb) => {
if (!company) {
throw Error("Company cannot be found!");
}
let companyName = req.company.name;
let path = `./uploads/${companyName}/files`;
if (!fs.existsSync(path)) {
fs.mkdirSync(path, { recursive: true });
}
cb(null, path);
},
filename: async (req, file, cb) => {
// ** with student auth Code
req.filename = req.company.name;
cb(null, filename + path.extname(file.originalname));
},
}),
}).single("company-file");
// Add Company
module.exports.add_company = async (req, res) => {
try {
// Here I want to extract that company object to create new company
console.log(req.file);
try {
const newcompany = await Company.create(company);
req.company = newcompany;
upload(req, res, async () => {
try {
const companyFile = await CompanyFile.create({
companyId: req.company._id,
path: `./uploads/${req.company.name}/file/${req.filename}.pdf`,
});
req.companyFile = companyFile;
} catch (err) {
res.status(400).json({ success: false, message: err.message });
// ** code for resume-upload using student authentication middleware
if (
fs.existsSync(
`./uploads/${req.company.name}/file/${req.filename}.pdf`
)
) {
fs.unlink(`./uploads/${req.company.name}/file/${req.filename}.pdf`);
}
}
});
res.status(201).json({
success: true,
message: "Company Drive Added Successfully.",
company: req.company,
companyFile: req.companyFile,
});
} catch (err) {
res.status(400).json({
success: false,
errors: err,
message: "Error while applying company drive.",
});
}
} catch (err) {
console.log(err);
}
};
From the docs:
Multer adds a body object and a file or files object to the request
object. The body object contains the values of the text fields of the
form, the file or files object contains the files uploaded via the
form.
So in your case, you can access and parse the company field by doing:
const company = JSON.parse(req.body.company);
Also, you need to make sure to apply the multer middleware to your controller, e.g.
app.post('/company/add', upload.single('company-file'), function (req, res, next) {
// req.file is the `company-file` file
// req.body.company will hold the company text field
})
I created a node API using multer to store files and i'm getting error while calling it, please help. Bellow is the code and error -
Code -
const storage = multer.diskStorage({
destination: './public/upload',
filename: function(req, file, cb){
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
// initialize upload
const upload = multer({
storage: storage,
limits: {fieldSize: 100000}
}).single('myImage');
app.post('/upload', (req, res)=> {
upload(req, res, (err) => {
if(err){
res.json({
msg: req.body,
});
}else {
res.json({
msg: 'File uploaded',
file: `upload/${req.file.filename}`
});
}
})
})
The error i'm getting while making API call is "name": "MulterError", "message": "Unexpected field", "code": "LIMIT_UNEXPECTED_FILE", "storageErrors": []
Passing the filename works for me -
uploadFile = (e) =>{
let file = e.target.files[0];
let data = new FormData();
data.append('myImage', file);
axios.post('http://localhost:5000/upload', data, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(res => this.setState({file: res.data.file}));
}
On your Frontend code have you made sure the input name is myImage
If you are using HTML try using this code
<input type=“file” name=“myImage” />
Suppose you are using the front end framework react
This piece of code should be in the submit/ uploadFile function
const uploadFile = (e) =>{
e.preventDefault();
let file = e.target.files[0];
let data = new FormData();
data.append('myImage', file);
axios.post('http://localhost:5000/upload', data, {
headers: {
'Content-Type': 'multipart/form-data'
}
}).then(res => this.setState({file: res.data.file}));
}
I hope this helps
limits: {fileSize: 100000}
I didn't check it but I believe it has to be fileSize not fieldSize, probably
I have an express server that gets a list of podcasts, from an endpoint.
This apart works fine, but there is a token that I use in requests to authorize entry to the endpoints.
the response when gaining an access token looks like:
{ access_token: '8c9d31761cbd32da25f1f1b988b527cde01c9d8a',
expires_in: 604800,
token_type: 'Bearer',
scope: 'podcast_read episode_read podcast_update episode_publish' }
I have a refresh token that I use when refreshing the token and works well.
The way I'm doing it at the moment is, I have a text file that holds the token, the app reads from this when making a request, I have set up a function, that is called every time the podcasts route is called router.get('/podcasts', checkIfTokenValid, (req, res, next) => { to check if the token is valid or expired if so, refresh the token and write the new token to the file.
The only thing about this is; the write to file function is executed after the podcasts route connects to the endpoint, so the old access token is used.
Logging to the console, the functions are executed before the podcasts route gets all the podcasts, except for the writeAccessTokenToFile() function.
Just wondering, is there a better way to do this?
var express = require('express');
var router = express.Router();
var app = express();
var path = require('path');
var fs = require('fs');
const request = require('request');
var refreshToken = '425153ed4ddb4aee5sjsjsfaeffc46ab9944aece0400f';
var clientId = 'myId';
var client_secret = 'secret';
var isAccessTokenValid;
var access_token_file = path.join(__dirname, 'access_token.txt');
function refreshAccessToken() {
console.log('refreshAccessToken')
var body = { 'grant_type': 'refresh_token', 'refresh_token': refreshToken }
var options = {
url: `https://api.podbean.com/v1/oauth/token`,
headers: { 'Authorization': 'Basic ' + new Buffer(clientId + ":" + client_secret).toString('base64') },
json: body
}
request.post(options, (err, response, body) => {
// console.log(body.expires_in*1000)
if (err) {
return response.status(500).json({
title: 'An error has occured',
error: err
})
}
console.log(body)
writeAccessTokenToFile(body.access_token);
})
}
function getAccessToken() {
return fs.readFileSync(access_token_file, 'utf8');
}
function writeAccessTokenToFile(token) {
console.log('writeAccessTokenToFile = '+ token)
var data = getAccessToken();
var result = data.replace(data, token);
fs.writeFileSync(access_token_file, result, 'utf8');
}
function checkIfTokenValid (req, res, next) {
console.log('checkIfTokenValid')
var options = {
url: `https://api.podbean.com/v1/oauth/debugToken?access_token=${getAccessToken()}`,
headers: { 'Authorization': 'Basic ' + new Buffer(clientId + ":" + client_secret).toString('base64') }
}
request(options, (err, response, body) => {
if (err) {
return res.status(500).json({
title: 'An error has occured',
error: err
})
}
// console.log(JSON.parse(body))
isAccessTokenValid = JSON.parse(body).is_valid;
if (isAccessTokenValid) {
refreshAccessToken();
}
next();
})
};
router.get('/podcasts', checkIfTokenValid, (req, res, next) => {
var options = {
url: `https://api.podbean.com/v1/podcasts?access_token=${getAccessToken()}`
}
request(options, (err, response, body) => {
if (err) {
return res.status(500).json({
title: 'An error has occured',
error: err
})
}
res.json(JSON.parse(body));
next();
})
});
module.exports = router;
Trying to upload pdf file on node js server using fetch() on client and express + multer on server, query status 200, but there is emty object in req.body and empty req.file. Pls check my code below on client.
client.js
fetch(path, conf) {
let myConf = config;
return fetch(myConf.apiUrl + path, conf)
.catch(err => {
console.warn('api error: ' + err.message)
})
},
sendForm(data) {
if (!data) {
return
}
let header, body;
const fd = new FormData();
fd.append('file', data.file.files[0])
header = 'application/pdf';
body = fd;
return this
.fetch('/connect', {
method: 'POST',
headers: {
'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
'Content-Type': header
},
body: body
})
.then(res => {
if (!res.ok) throw new Error('error ' + res.status)
return res
})
}
And server side:
server.js
const express = require('express');
const multer = require('multer');
const upload = multer({ dest: './uploads/' });
const app = express();
app.post('/connect', upload.single('resume'), function(req, res, next) {
res.send({
body: req.body,
file: req.file,
files: req.files
})
});
Result in Postman: http://prnt.sc/e1ib8o
i send a file from "react dropzone component" to "node server" and try to upload this with "multer" but no show any error, the file no upload and req.file/s is undefined
var express = require('express');
var router = express.Router();
var msg = require('../helpers/MessageHandler');
var CM = require('../helpers/ContentMessages.json');
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'public/uploads/');
},
filename: function(req, file, cb) {
cb(null, Date.now() + file.originalname);
}
});
var upload = multer({storage: storage}).any();
var path = '/enterprise';
router.post(path, function(req, res, next) {
var enterprise = req.body.obj;
console.log(req.body);
console.log(req.files);
console.log(req.file);
upload(req, res, function(err) {
if(err) {
return res.status(500).json(msg.prototype.errorMsg(err));
} else {
return res.status(200).json(msg.prototype.success(CM.message.success.doc_create, null));
}
});
});
the react component is somthing like this,
in the fetch function i send a object with all the fields
insertObj (values) {
console.info(values);
const obj = JSON.stringify({obj: values});
let url = '/api/v1/enterprise';
const headers = { 'Content-Type': 'application/json', 'Access-Control-Request-Method': '*'};
const req = new Request(url, {method: 'POST', headers: headers, body: obj});
fetch(req)
.then((response) => {
return response.json();
})
.then((enterprise) => {
console.log(enterprise);
}).catch((error) => {
console.log(error);
});
}
inside multer req.files will be visible. So change your code to this:
upload(req, res, function(err) {
var enterprise = req.body.obj;
console.log(req.body);
console.log(req.files);
console.log(req.file);
if(err) {
return res.status(500).json(msg.prototype.errorMsg(err));
} else {
return res.status(200).json(msg.prototype.success(CM.message.success.doc_create, null));
}
});
Also instead of 'Content-Type': 'application/json' there should be enctype='multipart/form-data'.