Get File from POST request body NodeJS & Angular - javascript

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.

Related

Uploading a file using Node without changing to a new page

I've been following some tutorials on how to upload a file using node and I've had success in actually uploading the file (I've primarily used https://www.geeksforgeeks.org/file-uploading-in-node-js/). However, every time it uploads the file, it changes to a new page. Is there a way to stay on the same page after uploading the photo, or do I have to create an HTML file with the same name with the same HTML as before the upload? The working code is below:
const express = require("express")
const path = require("path")
const multer = require("multer")
const app = express()
app.use(express.static(__dirname + '/public'));
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads")
},
filename: function (req, file, cb) {
cb(null, file.fieldname + "-" + Date.now()+".jpg")
}
})
var upload = multer({
storage: storage,
fileFilter: function (req, file, cb){
var filetypes = /jpeg|jpg|png/;
var mimetype = filetypes.test(file.mimetype);
var extname = filetypes.test(path.extname(
file.originalname).toLowerCase());
if (mimetype && extname) {
return cb(null, true);
}
cb("Error: File upload only supports the "
+ "following filetypes - " + filetypes);
}
}).single("myfile");
app.get("/",function(req,res){
res.render("Signup");
})
app.post("/uploadCode",function (req, res, next) {
upload(req,res,function(err) {
if(err) {
res.send(err)
}
else {
res.send("Success, Image uploaded!")
}
})
})
app.listen(8000,function(error) {
if(error) throw error
console.log("Server running on port 8000")
})
If you do the upload from a form where the browser submits the form for you automatically via a submit button, then it will be a browser form POST and the browser will automatically display whatever that POST request returns as the response.
If you, instead, upload form a form with a Javascript Ajax call to do the form POST, then the form response just comes back to your Javascript and nothing happens to the current web page in the browser. Your Javascript can receive that response and then decide what to do with it (if anything).
You've shown your server-side code here, but it's actually the client-side that controls what happens after the response from the upload is received back from the server. So, the changes would have to be made on the client-side to submit your form via Javascript.

Uploading a file to nodeJS server

Client code:
var data = new FormData();
data.append(fileName, blob, 'test.html');
fetch('http://localhost:3000/', {
method: 'POST',
headers: {
},
body: data
}).then(
response => {
console.log(response)
}
).then(
success => {
console.log(success)
}
).catch(
error => {
console.log(error)
}
);
Server code:
router.post('/', urlencodedParser, function(req, res, next) {
const body = req.body;
console.log(body);
res.send(`You sent: ${body} to Express`);
});
I am sending a blob in the body of a post request. When I send it to the server I want the server to download the file from the body of the request. How can i download this file? Or is there a simpler way to upload from client?
If you can utilize an NPM package formidable, there appears to be a solution at: https://www.w3schools.com/nodejs/nodejs_uploadfiles.asp
Once you have the file received, you can use the fs module to save and store in server
May it can solve your problem.
const fs = require('fs');
let directory = '/temp/data'; // where you want to save data file
router.post('/', urlencodedParser, function(req, res, next) {
const body = req.body;
console.log(body);
fs.writeFile(directory, body, function(err) {
if(err) {
return console.log(err);
}
console.log("File has been saved");
});
res.send(`You sent: ${body} to Express`);
});
This solved my answer - https://attacomsian.com/blog/uploading-files-nodejs-express, which basically uses a middleware to do the upload.
This was basically like:
const x = 6;
console.log(x);
Error: value is f'd up
const x = 6;
magic.valueParse(x);
console.log(x);
6
Also, i would like to point out how bodyParser cannot be used for multipart data. It is mentioned on the official docs, but even responses I get seem to point to bodyParser. So I thought I'd re-iterate that.

How to write a zip file from a request body to a file on Node server?

I am trying to write a node server that can receive a zip file of PDFs and JSON. In order to utilize it on the server I need to write it to a file on the server where I can call other functions on the internal data.
However with my current method, I can successfully write to a file in the server but when trying to open it in windows, I get an error "The Compressed (zipped) Folder is invalid."
I've tried directly piping the request to fs.createWriteStream with the same result as the code below
app.route('/myRoute').post(rawParser, function (req, res, next) {
let serverFileName = `${req.connection.remoteAddress.substring(7)}_${Date.now()}.zip`
let writeStream = fs.createWriteStream(`${__dirname}/${serverFileName}`, 'binary');
// console.log(req.rawBody);
writeStream.write(req.rawBody);
writeStream.end();
writeStream.on('error', err => {
logger.logger(err);
res.status = 500;
res.send("Server did not accept File");
});
writeStream.on('finish', () => {
logger.logger(`Writing to file: ${serverFileName}`);
res.status = 201;
res.send("Successfully Wrote file to server");
});
});
Here is my rawParser middleware
const rawParser = function (req, res, next) {
req.rawBody = [];
req.on('data', function (chunk) {
req.rawBody.push(chunk);
console.log(chunk)
});
req.on('end', function () {
req.rawBody = Buffer.concat(req.rawBody);
next();
});
}
I'm fairly new to node and javascript coding. I am welcome to any tips including your solutions

FormData server side NodeJS

I'm developing a web application using nodejs server-side. I'm trying to send pdf files from client to server.
Client:
var files = new FormData();
var count = 0;
$('#tableSlideId tr').each(function() {
var inputForm = $(this).find("th:first").children();
file = inputForm[0].files[0];
files.append((count++).toString(),file);
});
$.ajax({
type: "POST",
url: "/sendFiles",
data: files,
contentType: false,
processData: false,
}).done(function(err){
var text ="";
if(err) {
text = "Upload FAILED! Retry ...";
} else {
text = "Upload SUCCES!";
}
alert(text);
});
I think the client side is ok, infact if I use this loop:
for(var p of files)
console.log(p);
I correctly visualize all the elements that I want to send to the server.
Server:
app.post('/sendFiles', function(req,res) {
console.log("--->",req.body);
res.end();
});
Now in the server I have no idea how to visualize the data that I send, infact req.body is empty.
I don't know if this is the right way but my goal is to load some pdf files form the client, send to the server and after store them in a mySql dmbs.
Thank you.
Use express-formidable module. install 'express-formidable' by the running command
npm install express-formidable --save
a simple example is as follows from github
const express = require('express');
const formidable = require('express-formidable');
var app = express();
app.use(formidable());
app.post('/upload', (req, res) => {
//req.fields contains non-file fields
//req.files contains files
console.log(req.fields);
console.log(req.files);
});
Hope this helps!
Edit, from here -
app.post('/submit-form', (req, res) => {
new formidable.IncomingForm().parse(req, (err, fields, files) => {
if (err) {
console.error('Error', err)
throw err
}
console.log('Fields', fields)
console.log('Files', files)
files.map(file => {
console.log(file)
})
})
})
I think you need some middleware to accept the multipart formdata in the server side. Multer is a good option.
You can use
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
and then update your server side to handle the upload:
app.post('/sendFiles', upload.array('files', maxCount), function(req,res)

Error using fastify-multer to upload images

I am trying to use the fastify-multer plugin to upload files to the server and I am able to successfully get the images uploaded to the folder.
The problem is my app crashes.
I used the fastify-cli generated structure and I am running it as a standalone server as mentioned in the README.md here.
I am writing it as a fastify plugin.
"use strict";
const fp = require("fastify-plugin");
module.exports = fp(function(fastify, opts, next) {
fastify.decorate("uploadImage", function(request) {
const path = require("path");
const multer = require("fastify-multer");
var storage = multer.diskStorage({
destination: path.join(path.join(__dirname + "/uploads/")),
filename: function(request, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({ storage }).single("myImage");
upload(request, function(err) {
if (err) {
console.log(err);
} else {
console.log("Saved...");
return { saved: true };
}
});
});
next();
});
And here is the error I get :
Hi looked into your issue. You are using fastify-multer in the wrong way.
Invoking multer({ storage }).single("myImage") you are creating a fastify's preHandler hook that accepts 3 specific parameters. You can find more on the offical documentation. A simple working example could be the one you can see at fastify-multer:
const server = fastify()
// register fastify content parser
server.register(multer.contentParser)
server.route({
method: 'POST',
url: '/profile',
preHandler: upload.single('avatar'),
handler: function(request, reply) {
// request.file is the `avatar` file
// request.body will hold the text fields, if there were any
reply.code(200).send('SUCCESS')
}
})
If you need more help just provide me a repro repo on github and I'll try to figure out what is the best solution for your case.
Let me know! :)

Categories

Resources