Extracting uploaded csv data with multer - node.js

I am porting a rails app over to use the MEEN stack (Mongo, Express, Ember, Node)
I have a function that takes an uploaded csv and extracts the data from it and uses the data to then form SQL queries to a database. For some reason I am having issues with accessing the uploaded csv data with multer.
My Router file
var quotes = require('../api/quote');
var cors = require('cors');
var sku = require('../api/tools/sku');
var multer = require('multer');
var upload = multer({ dest: 'uploads/' });
var util = require("util");
var fs = require("fs");
var corsOptions = {
origin: 'http://localhost:4200'
}
module.exports = function(router){
router.route('/quotes').post(cors(corsOptions),function(req,res){
console.log(req.body);
quotes.addQuote(req,res);
}).get(cors(corsOptions),function(req,res){
quotes.getAllQuotes(req,res);
});
router.route('*').get(cors(corsOptions), function(req,res){
res.sendFile('public/index.html',{root:'./'});
});
router.post('/tools/sku/reactivate',upload.single('csvdata'),function(req,res){
console.log(req.files);
console.log('handing request over to sku.reactivate');
sku.reactivate(req,res);
});
};
My handlebars file for the tools/sku/reactivate template
<div class="col-md-8 col-md-offset-2 text-center">
<h2 class="toolTitle">Reactivate SKUs</h2>
<p class="lead">CSV Should Contain 1 Column (SKU) Only</p>
{{file-upload enctype="multipart/form-data" type="file" url="/tools/sku/reactivate" class="center-block" accept="text/csv" name="csvdata"}}
</div>
i am getting Error: Unexpected field when I attempt to post the file upload to the /tools/sku/reactivate post route. I don't understand whats wrong with my code.

The issue was using the file-upload ember addon. As soon as I removed the handlebars component and just hardcoded a form as seen below, the file upload's successfully.
<div class="col-md-8 col-md-offset-2 text-center">
<h2 class="toolTitle">Reactivate SKUs</h2>
<p class="lead">CSV Should Contain 1 Column (SKU) Only</p>
<form action="/tools/sku/reactivate" method="POST" enctype="multipart/form-data">
<input class="center-block" type="file" name="csvdata">
<button type="submit" class="btn btn-md btn-danger">Submit</button>
</form>
</div>

Related

Image is not showing up on frontend after fetching from mongoDB

Hello i am working on my fyp and i am new to react js and node js i have successfully stored my image in mongoDB database when i upload the image the image is stored in a local storage in my case it is stored in a folder named "uploads" and the name of image is stored in database and when i try to fetch image by giving path of locally stored image + name stored in database it does not show any image rather it shows a broken image. the name of the image is stored in a variable name "profileImage" and it is retrieving from database properly. dont know what is the issue anyone here to guide me . Screenshot of output and code is attached for reference.
Code For Frontend and get api
import React, { useEffect,useState } from 'react';
import {useHistory} from "react-router-dom";
import axios from 'axios'
const About = () =>{
const history = useHistory();
const [id, setID] = useState('');
const [name, setName] = useState('');
const [email, setEmail] = useState('');
const [phone, setPhone] = useState('');
const [work, setWork] = useState('');
const [profileimage, setPimage] = useState('');
const CallAbtPageA=()=>{
axios.get('/about')
.then((res) => {
setID(res.data.id);
setName(res.data.name);
setEmail(res.data.email);
setPhone(res.data.phone);
setWork(res.data.work);
setPimage(res.data.photo);
})
.catch((error) => {
console.log(error);
history.push('/login');
});
}
useEffect(()=>{
CallAbtPageA();
});
return(
<div>
<form method="GET" encType="multipart/form-data">
<div> <h1 style={{display:'inline',color:'black'}}>ID:</h1> <p style={{display:'inline',fontSize:"35px"}}>{name}</p> </div>
<div> <h1 style={{display:'inline',color:'black'}}>Name:</h1> <p style={{display:'inline',fontSize:"35px"}}>{name}</p> </div>
<div> <h1 style={{display:'inline',color:'black'}}>EMAIL:</h1> <p style={{display:'inline',fontSize:"35px"}}>{email}</p> </div>
<div> <h1 style={{display:'inline',color:'black'}}>PHONE:</h1> <p style={{display:'inline',fontSize:"35px"}}>{phone}</p> </div>
<div> <h1 style={{display:'inline',color:'black'}}>WORK:</h1> <p style={{display:'inline',fontSize:"35px"}}>{work}</p> </div>
</form>
<div> <h1 style={{display:'inline',color:'black'}}>PROFILE PIC:</h1> <img src = {`./uploads/${profileimage}`} /> </div>
</div>
)
}
export default About;```
[![Screenshot of output][1]][1]
[1]: https://i.stack.imgur.com/oWtw4.png
[![Screenshot of Response is in below link][2]][2]
[2]: https://i.stack.imgur.com/pVPfi.png
It is because your uploads folder is not acccessed publicly. So, to resolve this you have to serve the folder as static in Express.
Try this in nodejs:
app.use('/uploads',express.static('uploads'))
what is your api backend? image is not found there because may be you are not serving your static image assets.

how to send the selected drop down element from client to server using node js - express

I am new to node js and i am stuck to send the selected drop down element (like java,angular see below ex ) from client to server using node js - express. When i try to print it in console. system displays an error message "undefined " for drop down elements. Please help me on this. Thanks in advance.
EJS code
<form method="POST" action="/viewreg.html">
<select name="Courses" form="Courses">
<option value="Java">Java</option>
<option value="Angular">Angular</option>
<option value="Automation">Automation</option>
</select>
<input type='submit'name ='register' onclick="form.action='viewreg.html'"
</form>`
Server side -
const http = require('http');
const express = require('express');
const bodyparser=require('body-parser');
const path=require('path');
const hostname = 'x.x.x.x'
const port = 80;
const app = express();
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({extended:true}));
app.use(express.static(path.join(__dirname,'public')));
app.set('view engine','ejs');
app.set('views',path.join(__dirname,'views'));
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({extended:true}));
const dir=path.join(__dirname,'public');
app.set('view engine','ejs');
app.set('views',path.join(__dirname,'views'));
app.post('/viewreg.html',function(req,res) {
const newuser= {
emp_name:req.body.emp_name,
emp_id:req.body.emp_id,
phone_no:req.body.phone_no,
Team:req.body.selectpicker,
courses:req.body.Courses,
}
console.log(newuser);
});
You need to revisit the below issues which exist in your code.
Change your action url from action="/viewreg.html"> to
action="/viewreg">
There is no need to have onclick="form.action='viewreg.html'" in
your submit button.
You don't have an ID attribute attached to your <select> tag
where as you have a form attribute incorrectly over there.
You need to re-write your ejs tempalte as,
<form method="POST" action="/viewreg">
<select name="Courses" id="Courses">
<option value="Java">Java</option>
<option value="Angular">Angular</option>
<option value="Automation">Automation</option>
</select>
<input type='submit'name ='register'>
</form>
Also try changing your console.log(newuser); as,
console.log(req.body.Courses);
which will resolve your issue.
Hope this helps!

(Self Q&A) HOW TO SETUP AND USE the MULTER MIDDLEWARE) for single file upload ( Expressjs/Nodejs )

Just wanted to post an answer to a beginner level question on HOW TO SETUP AND USE the MULTER MIDDLEWARE in Expressjs/Nodejs
Hope this saves your time
There should be two files:
1.Jade file(which shall contain the form lets assume index.jade)
2.JS file(which is located in the routes folder, and which directs to the index.jade file in the views folder)
SETUP index.jade file
//not a jade file so convert it to jade
//enctype is set to multipart/form-data --- multer requirement
<form method="post" role="form" enctype="multipart/form-data">
<div class="form-group">
<label for="upload">Email address:</label>
//name attribute to access in index.js route file
<input type="file" class="form-control" name="upload" id="upload">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
//very important
(a)In the Jade file the form must contain the attribute of enctype = "multipart/form-data"
(b)Input should have a name attribute which gets accessed in the index.js file
SETUP JS ROUTE FILE(index.js) not in app.js
var express = require('express')
var multer = require('multer')
var upload = multer({ dest: 'uploads/' }) //set dest to where you want to upload the file
var app = express()
// SINGLE FILE UPLOAD
app.post('/', upload.single('upload'), function (req, res, next) {
//since we are performing a single file upload req.file will be used and not req.files
// req.file would attach the file with upload fieldname ~ upload is the name attribute given in the form
//now use req.file to access the file
//for example
console.log(req.file); // this would display the file attributes in the log
})

What am i missing for the file upload using multipart form data ?

Hi for whatever reason i cannot use packages e.g. multer to upload file to node server. So i found example online, if just upload file in the form, it works fine.
Now i want to send another field "password" together with the file during submit, just cannot make it a work.
I do know there're plenty modules out there, for now just want to this example to work.
<form style="height: 100%;padding-bottom:63px;">
<p>
<input type="file" class="FirmwareFile"
name="myUpload" file-model="upload.newFwFile">
</p>
<p>
<input type="password" name="password" id="password"
placeholder="Password"
ng-model="upload.controllerPassword"
class="formInput">
</p>
</form>
httpSvc.uploadToUrl(myFile, myPd, myServerIPAddress, myRoute) {...}
factory.uploadToUrl = function (fwFile, pd, myServerIp, myRoute) {
var fd = new FormData();
//fd.append('passwd', pd); // cannot pass password to server side ?
fd.append('file', fwFile); // only this works
var deferred = $q.defer();
var completeUrl = ......
$http.post(completeUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).success(function (data) {
deferred.resolve(data);
}).error(function () {
deferred.reject();
});
return deferred.promise;
}
in server side, where to extract the password info please ?
var UploadImage = function(req, res, callback){
var destFile = fs.createWriteStream(uploadDest + "mytest");
var fileSize = req.headers['content-length'];
req.pipe(destFile); //why not sth. like req.body.file.pipe() ?
...
};
Your form does not have
<form enctype="multipart/form-data" action="..." method="...">
...
</form>
You will be better off using node-formidable. The example works straight out of the box. You might also want to look into angularJS specific form upload directives that have been made. No sense in reinventing the wheel.
Cheers

How to upload a file to Parse.com using simple HTML form?

I want to upload a simple image file along with text value to a Parse.com project at www.willubmy.com/create. But either I am not getting the correct enctype or Parse's node requires some changes. Can you please help resolve this issue? I am getting the POST variables normally but am not able to get anything when I send a file along
Simplified HTML
<form>
Question:<br>
<input type="text" name="questionString">
<br>
username:<br>
<input type="text" name="username">
<input type="file" name="file">
</form>
My Cloud Code
app.post('/create', function(req, res) {
var username = req.body.username;
var questionString = req.body.questionString;
var positiveAnswer = req.body.positiveAnswer;
var negativeAnswer = req.body.negativeAnswer;
var email = req.body.email;
console.log(username + questionString + positiveAnswer + negativeAnswer + email + JSON.stringify(req.body));
console.log("req files : " + req.files);
This documentation can help you:
https://www.parse.com/questions/uploading-files-to-parse-using-javascript-and-the-rest-api

Resources