Cannot upload file on server nodeJs - javascript

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

Related

Express fetching data promise is pending

I've written 2 snippets of code - client and server. When the client clicks the button he sends information to the server, which uses the Riot API to retrieve summoner info. Now I want to send it back to the client but once I fetch it my promise response is pending and result is undefined. Promises are a new thing for me. Here's the code,
Client:
<!DOCTYPE html>
<html>
<head>
<script>
function sendInfo(){
let name = document.getElementById("checker").value;
let data = {name};
fetch("/api", {
method: "POST",
headers: {
"Content-type": "application/json"
},
body: JSON.stringify(data)
});
//let data = document.getElementById("levelID");
fetch("/level", {
headers : {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(function(res){
console.log(res.json());
})
.then(function(data){
console.log(data);
})
.catch(function(error){
console.log(error);
});
}
</script>
</head>
<body>
<input type="text" name="checkPlayer" id="checker"><br>
<button onclick="sendInfo()">Search summoner!</button>
</body>
</html>
Server:
const PORT = 3000;
const axios = require("axios");
const express = require("express");
const path = require('path');
const key = "RGAPI-50e38ac8-4629-4abc-aef9-68e4259448bd";
const parser = require("body-parser");
var jsonParser = parser.json();
//let puuid, summonerID, level;
let summoner;
const app = express();
app.listen(PORT, () => {
console.log("listening at 3000");
});
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname, '/main.html'));
//searchBySummonerName("RnkzOnFire");
});
app.post("/api", jsonParser, (req, res) => {
searchBySummonerName(req.body.name);
});
app.get("/level", (req, res) => {
res.writeHead(200, {"Content-Type": "application/json"});
res.write(JSON.stringify(summoner));
});
function searchBySummonerName(name){
const searchURL = "https://eun1.api.riotgames.com/lol/summoner/v4/summoners/by-name/" + name + "?" + "api_key=" + key;
axios.get(searchURL).then((res) => {
summoner = res.data;
});
}

Getting error while making API call for multer to store files

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

sending a file with another data using axios with react

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.");
}

Express js post multipart form data to external API

I have an angular application and express server a middle ware which call the external API
$scope.uploadLayout = function(){
$scope.selectedTemplate.selected = $scope.items;
var fd = new FormData()
fd.append('name', $scope.template.name)
fd.append('description', $scope.template.desc)
fd.append('file', $scope.template.file)
$http.post('/layout/template',fd,{
transformRequest: angular.identity,
headers: { 'Content-Type': undefined}
}).then(function(response){
getLayoutRules()
console.log("file uploaded successfully")
})//add error callback
console.log('test')
}
The main problem occurs when express sends the data to the external API
app.post('/layout/template', upload.any(), (req, res) => {
// console.log(req.body.name);
var formdata = new Buffer(req.files)
var form = new FormData();
form.append('name', req.body.name)
form.append('description', req.body.description)
form.append('file', formdata)
console.log(form)
var contentLength = req.files.length;
var url = `${apiUrl}/layout/template`
// var r = request.post(url,{
// headers: { 'Content-Type': undefined}
// }, function optionalCallback(err, httpResponse, body) {
// if (err) {
// return console.error('upload failed:', err);
// }
// console.log('Upload successful! Server responded with:', body);
// })
request({
headers: {
'Content-Length': contentLength,
'Content-Type': 'multipart/form-data'
},
url:url,
method:'POST',
body: form
},function(err,body,res){
console.log(err)
console.log(body)
})
});
I have checked the form is generating properly but the external API server gives me an error saying that
"The request was rejected because no multipart boundary was found"
Kindly help, or is there any other way round it
UPDATE
I modified the code a bit to send the request headers fetched from the browser
app.post('/layout/template', upload.any(), (req, res) => {
var header = req.headers['content-type']
var formdata = new Buffer(req.files)
console.log(formdata)
var fd = new FormData();
fd.append('name', req.body.name)
fd.append('description', req.body.description)
fd.append('file', formdata)
//var contentLength = req.files.length;
//console.log(contentLength)
var url = `${apiUrl}/layout/template`
//console.log(fd)
// var r = request.post(url,{
// headers: { 'Content-Type': undefined}
// }, function optionalCallback(err, httpResponse, body) {
// if (err) {
// return console.error('upload failed:', err);
// }
// console.log('Upload successful! Server responded with:', body);
// })
request({
headers: {
'Content-Type': header
},
url:url,
method:'POST',
body: fd
},function(err,body,res){
//console.log(body)
console.log(res)
})
//console.log(request)
});
So now i am sending the same boundary set by browser but now the form parameters are not detected by java server

react / expressjs / multer don't save image

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'.

Categories