I have a pdf generated file on the front end of my application that I got using html2pdf plugin. I have a nodemailer server at my backed where I can attach files and send it to an email of my choice. Is there a way I can send the pdf that is generated in the front end to Nodejs? I am also using express
Edit:
Based on your advice I did
**On the Client side**
var element = document.getElementById('element-to-print');
const elem = document.getElementById('html');
html2pdf().from(element).toPdf().get('pdf').then(function (pdf) {
window.open(pdf.output('bloburl'), '_blank');
var formData = new FormData();
formData.append("filename", pdf);
axios.post('/upload',formData).then(res => { console.log(res) })
// formData.append("uploadedFile", fileInputElement.files[0]);
})
On express app
app.post('/upload', fileUpload(), function(req, res) {
const sampleFile = req.files.uploadedFile;
// do something with file
res.send('File uploaded');
})
But I get this error coming from index.js
TypeError: Cannot read property 'uploadedFile' of null
Yes.
Create and endpoint/route in your express app
Use a http agent like superagent, request or axios in your client
Use multipart form or something like FormData to create the data that is supposed to be sent.
Post it to the url you created in express.
Use middlewere such as express-fileupload or busboy to handle the attachment.
So in your client. You have something like
var formData = new FormData();
formData.append("filename", "My awesome file");
formData.append("uploadedFile", fileInputElement.files[0]);
Then you post that with something like Axios
axios.post('/upload',formData).then(res => { console.log(res) })
In your express app you do something like
const express = require('express');
const fileUpload = require('express-fileupload');
const app = express();
app.post('/upload', fileUpload(), function(req, res) {
const sampleFile = req.files.uploadedFile;
// do something with file
res.send('File uploaded');
})
<form method="post" enctype="multipart/form-data" action="/">
<div>
<label for="profile_pic">Choose file to upload</label>
<input type="file" id="profile_pic" name="profile_pic"
accept=".pdf">
</div>
<div>
<button>Submit</button>
</div>
For receive it at node you have to define a new route at the same path.
Related
I want to store the image uploaded in a simple html input
<input
type="file"
name="thumbnail"
id="image-input"
accept="image/png, image/jpg, image/jpeg"
hidden
/>
This leads to a post request when submitted
router.post('/dish/new',async (req,res) => {
let { name, desc, cost, isnonveg, thumbnail} = req.body;
fs.writeFile(path.join(__dirname,'../userdata/images/dishes','g.jpg'),thumbnail, ()=>{
console.log('image stored')
})
})
I want to store whatever the user uploads using node fs
How can I go about doing this.
The approach I use here merely stores the name of the file instead of the actual file.
if you are using express you can add this attribute to form tag enctype="multipart/form-data". Then your image will be sent from frontend . To receive the image in the server you need to configure a middleware called express-fileupload
var fileupload = require("express-fileupload");
then you can register the middleware by app.use(fileupload()); in your app.js file
in your route file
router.post('/something', async (req, res) => {
let image=req.files.fieldName
})
image.mv('./public/images/foldername/' + 'imageName' + '.jpg', (err) => {
if (err) {
console.log(err)
} else {
res.redirect('/)
}})
once it is done when you submit your form you can see the uploaded image in your server /public/images/foldername .
I made a simple nodejs server which serves a html page to the user.The page contains a input text box of userID. When the user presses the button submit, I take that userID entered by the user and put it in form Data and send it to my server function (submitForTest) through POST method.
Now, inside my function of nodejs which handles submitForTest, I tried to access the userID , but I was getting res.body as {} , so not able to figure out how to access userID here.
Can anyone please point what I need to get the userID at my node js code.
My HTML file :
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
<label>User ID</label>
<div>
<input type="text" id="userid" >
</div>
</div>
<div>
<div>
<button type="submit" onclick="submitForTest()">Submit</button>
</div>
</div>
<script type="text/javascript">
function submitForTest()
{
var userID = document.getElementById('userid').value;
let formData = new FormData();
formData.append("userID", userID);
//alert("hello");
fetch('http://MY-SERVER:3000/submitForTest', {method: "POST", body: formData});
}
</script>
</body>
</html>
My Node js file :
'use strict'
const fs = require("fs")
const express = require('express')
var path = require('path')
const app = express()
var bodyParser = require('body-parser')
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
var jsonParser = bodyParser.json();
app.get('/',function(req,res) {
res.sendFile('small.html');
});
app.post('/submitForTest', function(req, res) {
//want to print userID here .. but the below is coming as {} here ..
console.log(req.body);
})
// Tell our app to listen on port 3000
app.listen(3000, function (err) {
if (err) {
throw err;
}
console.log('Server started on port 3000')
})
Please help.
Regards
The problem is FormData is sending body encoded as multipart/form-data. You'll have to add middleware able to handle multipart body format. Busboy or multer for example.
Example of using multer to upload a file and send userID field:
// --- form
<form action="/submitForTest" enctype="multipart/form-data" method="post">
<input type="file" name="uploaded_file">
<input type="text" name="userID">
<input type="submit" value="Submit">
</form>
// --- server
var multer = require('multer')
var upload = multer({ dest: './uploads/' }) // where the uploaded files will be stored
app.post('/submitForTest', upload.single('uploaded_file'), function (req, res) {
// req.file is the name of your file in the form above, here 'uploaded_file'
// req.body will hold the text fields, if there were any
console.log(req.file, req.body)
});
Or to send your data in urlencoded or json format. Something like that for json for example:
function submitForTest()
{
var userID = document.getElementById('userid').value;
fetch('http://MY-SERVER:3000/submitForTest', {
method: "POST",
headers: {
'Content-type': 'application/json',
},
body: JSON.stringify({ userID }),
});
}
This question already has an answer here:
Sending a CSV file from browser to nodejs server
(1 answer)
Closed 2 years ago.
On my frontend application, I have a form where a user can upload a file. I want to upload this file to my Node.js backend using the fetch API.
Frontend code
HTML:
<form id="forecast-form">
<input type="file" id="csvFile" />
<input type="submit" value="Submit" />
</form>
JavaScript:
const handleSubmit = (e) => {
e.preventDefault();
const csv = e.target.csvFile.files[0];
console.log(csv); // This actually logs the file object
const formData = new FormData();
formData.append('csvFile', csv);
const options = {
method: 'POST',
body: formData,
};
fetch('http://localhost:4000/api/v1/forecast', options)
.then((res) => res.text())
.then((data) => console.log(data)); // output: {}
}
Node.js + express code
create: async (req, res, next) => {
try {
const body = req.body;
console.log(body); // output: {}
res.status(201).send(body);
next();
} catch (err) {
next(err);
}
}
But the only output I get, both from the frontend and backend, is an empty object {}.
Edit:
I wouldn't say this question is a duplicate since the aforementioned question in mind is not specific to the fetch API, which this question is.
After finding some information from this question Sending a CSV file from browser to nodejs server
I realised I couldn't just use vanilla req.body like I do for json data, instead I need to use some sort of middleware to handle the multipart/form-data content type.
So I used the multer middleware
const multer = require('multer');
const upload = multer({ dest: 'uploads/' });
router.post('/forecast', upload.single('csvFile'), forecast.create);
Then on POST, the file will be uploaded under uploads/ and per multer documentation:
// req.file is the avatar file
// req.body will hold the text fields, if there were any
I am working on an MEAN Stack application and I am trying to manage a form that allows users to upload a file when they submit. It appears to be working on the client side, however when I send the post request from the client and inspect the request body the file is an empty object. It is just a small .docx file so it should be fine size-wise. But I do not understand why nothing is properly received since the request goes through with out error. I was under the impression that files could be sent this way.
Am I missing something?
code from angular service
sendApplcation(data : any): Observable <any>
{
return this.http.post(this.url+ '/careers/api/application', data);
}
nodejs code
router.post("/api/application", (req, res) => {
const application = req.body;
console.log(req.body.file);
let email = {
to: `${req.body.email}`,
from: "Careers#TrueLogistics.ca",
subject: "Application Recieved",
text: JSON.stringify(req.body),
html: `<p> ${JSON.stringify(req.body)} </p>`,
};
mailer.sendMail(email, (err, res) => {
if (err) {
console.log(err);
}
});
email.to = "mjayfalconi#gmail.com";
mailer.sendMail(email, (err, res) => {
if (err) {
console.log(err);
}
});
res.json("Applcation Submitted Successfully!");
});
Check out the multer package on npm.
File upload works a bit differently than the normal request.
You will also set enctype to multipart at the front end.
Furthermore, I see you are using nodemailer to send the file as an attachement. Read the documentation about the attachment. You don't send the file that way.
//Dependencies
const multer = require('multer');
//Multer DiskStorage Config
const diskStorage = multer.diskStorage(
{ destination: 'assets/profile_upload'} );
//Create Multer Instance
const upload = multer({ storage: diskStorage });
//File upload
//or app.post()
router.post('/upload-file', upload.single('file'), (req, res) => {
//The file
console.log(req.file)
;});
//Your code:
app.post('/upload', (req, res) => { ... try doing app.post('/upload' ,upload.single('file'),
Also check out this post: https://stackoverflow.com/a/61341352/9662626
Sorry for the bad formatting. I only have access to my phone at the moment.
I am sending a CSV file to my node + express server using jQuery's ajax POST method. When I post the csv file to my express route, I don't know how to access the file once it reaches the server. My goal is to pass the CSV file into my route's middleware called upload.single(). I'm also not sure which data type to specify for the ajax call.
Here is my form where I accept the CSV file:
<form onSubmit={this.handleSubmit.bind(this)} encType="multipart/form-data">
<input id="userFile" type="file" name="userFile"></input>
<input type="submit" name="submit" value="Upload New Candidates"></input>
</form>
Here is my handleSubmit function which makes the POST request:
handleSubmit(event) {
event.preventDefault();
var csvToSend = document.getElementById("userFile").files[0];
$.ajax({
type: "POST",
url: 'http://localhost:3000/',
data: csvToSend,
success: success,
dataType: //not sure what to put here
});
}
Here is my express route on the server. How should I access the CSV file sent from the client and enter it into the upload.single() middlware?
app.post('/', upload.single('userFile'), function(req, res, next) {
res.sendStatus(200);
});
As peteb mentioned it looks like you're using multer for a single file and so in that situation:
// If you set up multer to store files locally
const upload = multer({ dest: 'uploads/' });
const fs = require("fs");
app.post('/', upload.single('userFile'), async function(req, res, next) {
const filePath = req.file.path;
const fileData = await fs.promises.readFile(filePath); // Buffer of csv file
const csvString = fileData.toString();
// Do whatever you need to with the csv file
res.sendStatus(200);
});