How To Upload Multiple Image from Android to NodeJS server - node.js

I recently saw a tutorial to upload some photos from here [https://aguacatelang.wordpress.com/2012/08/19/android-multipart-upload-to-node-js/][1]
I've just learned nodejs and less understanding of the structure of programming languages, I found a mistake like this :
home/je/Documents/BE/UploadFoto/app.js:12
var db = new Db('photos', new dbServer('localhost', dbConnection.'27017', {}))
^^^^^^^
SyntaxError: Unexpected string
at Module._compile (module.js:439:25)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:935:3
this is original source code :
var express = require('express');
var app = express()
var fs = require('fs');
var im = require('imagemagick');
var Db = require('mongodb').Db;
var dbServer = require('mongodb').Server;
var dbConnection = require('mongodb').Connection;
var db = new Db('photos', new dbServer('localhost', dbConnection.'DEFAULT_PORT', {}));
db.open(function(err, db){});
app.use(express.bodyParser())
app.get('/', function(req, res){
res.send(
'<form action="/upload" method="post" enctype="multipart/form-data">'+
'<input type="file" name="source">'+
'<input type="submit" value="Upload">'+
'</form>'
);
});
app.post('/upload', function(req, res){
console.log("Received file:\n" + JSON.stringify(req.files));
var photoDir = __dirname+"/photos/";
var thumbnailsDir = __dirname+"/photos/thumbnails/";
var photoName = req.files.source.name;
fs.rename(
req.files.source.path,
photoDir+photoName,
function(err){
if(err != null){
console.log(err)
res.send({error:"Server Writting No Good"});
} else {
im.resize(
{
srcData:fs.readFileSync(photoDir+photoName, 'binary'),
width:256
},
function(err, stdout, stderr){
if(err != null){
console.log('stdout : '+stdout)
res.send({error:"Resizeing No Good"});
} else {
//console.log('ELSE stdout : '+stdout)
fs.writeFileSync(thumbnailsDir+"thumb_"+photoName, stdout, 'binary');
res.send("Ok");
}
}
);
}
}
);
});
app.get('/info', function(req, res){
console.log(__dirname);
res.send("ok");
});
app.listen(8000);
console.log('connected to localhost....')
I switched DEFAULT_PORT to 27017 because in my PC the port that is used mongodb:localhost/27017. May someone help me? thanks

BodyParser no longer supports parsing multypart requests. You should try using one of these modules.
busboy.
multiparty.
formidable.
multer.
Here is a simple example using multiparty:
var multipart = require('multiparty');
app.post('/upload', function(req, res){
var form = new multipart.Form();
form.parse(req, function(err, fields, files) {
console.log(files);//list all files uploaded
//put in here all the logic applied to your files.
});
return;
});
Or you can use it as a middleware, like this:
var multipart = require('connect-multiparty');
app.use(multipart());
app.post('/upload', function(req, res) {
console.log(req.files);//list all files uploaded
// apply all logic here
});

I am sending files like Audios,Images and videos etc from Android Using Retrofit ,At server side i am using node.js .
on btnUpload click i am uploading my files to server .
btnUpload.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(MusicActivity.this, ""+ commonAdapter.getSelectedItems().size(), Toast.LENGTH_SHORT).show();
String fileUri=null;
File file=null;
RequestBody requestFile=null;
MultipartBody.Part part=null;
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
for(int i=0;i<commonAdapter.getSelectedItems().size();i++)
{
fileUri = commonAdapter.getSelectedItems().get(i);
file = new File(fileUri);
requestFile = RequestBody.create(MediaType.parse(fileUri), file);
//music name must be same as music at node.js ,
//if its different then it will not worked.
part = MultipartBody.Part.createFormData("music", file.getName(), requestFile);
Call<UploadObject> myResponseCall = apiService.uploadMusic(part);
myResponseCall.enqueue(new Callback<UploadObject>() {
#Override
public void onResponse(Call<UploadObject> call, Response<UploadObject> response) {
Log.d("kkkk","ok response");
}
#Override
public void onFailure(Call<UploadObject> call, Throwable t) {
// Toast.makeText(ImagesActivity.this, "Error Occured ! ", Toast.LENGTH_LONG).show();
Log.d("kkkk","on failed");
}
});
}
}
});
My ApiInterface for Retrofit
public interface ApiInterface {
#Multipart
#POST("api/uploadImage")
Call<UploadObject> uploadImage(#Part MultipartBody.Part file);
#Multipart
#POST("api/uploadVideo")
Call<UploadObject> uploadVideo(#Part MultipartBody.Part file);
#Multipart
#POST("api/uploadMusic")
Call<UploadObject> uploadMusic(#Part MultipartBody.Part file);
}
Its my getSelectedItem :- which return selected Items
public ArrayList<String> getSelectedItems()
{
return selectedItems;
}
At Node.js I am using multer
var express = require('express')
//const bodyParser = require('body-parser');
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
var fs = require('fs');
var app = express()
// app.use(bodyParser.json());
// app.use(bodyParser.urlencoded({ extended: true }));
app.post('/api/uploadImage', upload.single('image'), function (req, res, next) {
var tmp_path = req.file.path;
var target_path = 'uploads/' + req.file.originalname;
/** A better way to copy the uploaded file. **/
var src = fs.createReadStream(tmp_path);
var dest = fs.createWriteStream(target_path);
src.pipe(dest);
src.on('end', function() { console.log('complete') });
src.on('error', function(err) { console.log('error'); });
fs.unlink(tmp_path);
});
app.post('/api/uploadVideo', upload.single('video'), function (req, res, next) {
var tmp_path = req.file.path;
var target_path = 'uploads/' + req.file.originalname;
/** A better way to copy the uploaded file. **/
var src = fs.createReadStream(tmp_path);
var dest = fs.createWriteStream(target_path);
src.pipe(dest);
src.on('end', function() { console.log('complete') });
src.on('error', function(err) { console.log('error'); });
fs.unlink(tmp_path);
});
app.post('/api/uploadMusic', upload.single('music'), function (req, res, next) {
var tmp_path = req.file.path;
var target_path = 'uploads/' + req.file.originalname;
/** A better way to copy the uploaded file. **/
var src = fs.createReadStream(tmp_path);
var dest = fs.createWriteStream(target_path);
src.pipe(dest);
src.on('end', function() { console.log('complete') });
src.on('error', function(err) { console.log('error'); });
fs.unlink(tmp_path);
});
app.listen(8080,(res,err)=>{
if(err)
console.log('error occured while connecting port');
else
console.log('Server is Up');
});
I hope its help You!

Related

Do variables reset to their initial values after every post method in Node.js?

//jshint esversion:6
var logger;
var logName;
var pollName;
var names = [];
const fs = require("fs");
const express = require("express");
const bodyParser = require("body-parser");
const readline = require('readline');
const fileName1 = __dirname + "/public/logger.json";
const fileName2 = __dirname + "/public/poll.json";
const dataWriter1 = require(fileName1);
const dataWriter2 = require(fileName2);
const app = express();
app.use(bodyParser.urlencoded({
extended: true
}));
var reader = readline.createInterface({
input: fs.createReadStream(__dirname + '/public/names.txt'),
console: false
});
reader.on('line', function(line) {
names.push(line);
});
app.use(express.static(__dirname + '/public'));
app.get("/", function(req, res) {
res.sendFile(__dirname + "/index.html");
});
app.get("/route", function(req, res)
{
fs.readFile(fileName1,'utf-8',(err,data)=>
{
res.set('Content-Type', 'application/json');
res.send(data);
});
});
app.post("/", function(req, res)
{
if(req.body.button==1)
{
logName = req.body.name;
console.log(logName);
for (i = 0; i < names.length; i++)
{
if (logName == names[i])
{
logger=true;
break;
}
}
if(logger!=true)
{
logger=false;
}
dataWriter1.logger = logger;
fs.writeFile(fileName1, JSON.stringify(dataWriter1), function writeJSON(err)
{
if (err) return console.log(err);
console.log(JSON.stringify(dataWriter1));
});
logger=false;
}
else if(req.body.button==2)
{
console.log(logName);
pollName=req.body.option;
for(i=0;i<dataWriter2.list.length;i++)
{
if(dataWriter2.list[i].name==pollName)
{
dataWriter2.list[i].votes++;
dataWriter2.list[i].voter_name.push(logName);
//logName is undefined
}
}
fs.writeFile(fileName2, JSON.stringify(dataWriter2), function writeJSON(err)
{
if (err) return console.log(err);
console.log(JSON.stringify(dataWriter2));
});
}
res.redirect("/");
});
app.listen(3000, function()
{
console.log("Server Started!");
});
This is my server code in node.js. I have 2 forms in index.html and both have submit buttons with different value to differentiate. The first form has to be submitted to view the second form. My problem is that even though I'm storing a data from the first form in a variable it resets when I submit the second form even though when the server is still running.
I cannot understand why logName becomes undefined while I'm posting with the second submit button and is there any workaround?
I figured it out.. The server was restarting due to changes in a JSON file as I was running it by nodemon. Added JSON file to ignore list and now it's all fine.

How to upload and download a file in a single service call in nodejs?

I can upload a file via postman and download a file from server in two different service .. But what i need is ..In a single call i should able to upload the file to server ,then perform some operation after performing some operation i should able to download the file automatically.
Here is my code.
My firsts service(file upload operation)
var express = require('express');
var fs = require('fs');
var formidable = require('formidable');
var router = express.Router();
/* GET home page. */
router.post('/', function(req, res, next) {
var form = new formidable.IncomingForm();
form.uploadDir="./file"
form.keepExtensions=true;
form.maxFileSize=10*1024*1024;
form.multiples=false;
form.parse(req, function (err, fields, files) {
res.write('File uploaded');
res.end();
});
});
module.exports = router;
Download service
var express = require('express');
var router = express.Router();
var express = require('express');
router.get('/', function(req, res, next) {
var file = './file/myOutput.txt';
var name = 'ENC.txt'
res.download(file, name);
});
module.exports = router;
Now i need to make this two service as one?
var express = require('express');
var formidable = require('formidable');
var app=express();
async function calculation(parameters)
{
if(parameters)
{
//Here you can do calculation depending upon parameter values
}
else
{
//Display error or as per your choice
}
}
app.get('/',function(req,res){
res.sendFile(__dirname+'/index.html');
});
async function cal(res,file,form)
{
try{
const data = await calculation(true)
if(data){
res.set({
'Location' : __dirname+'/index.html',
});
res.download( __dirname+file.name);
}
}
catch(error)
{
console.log(error);
}
}
app.post('/',function (req,res){
var form = new formidable.IncomingForm();
form.parse(req);
form.on('fileBegin',function(name,file){
file.path = __dirname+file.name;
console.log("Uploading");
});
form.on('file',
function(name,file)
{
console.log('Uploaded ',file.name);
cal(res,file);
});
});
Hope it helps

Nodejs - Video streaming problems

I'm having some problems when trying to stream videos in nodejs. When I tried just pass the video path to the source/video html tag, it doenst worked. Then, I realized that problably I would have to stream the video.
The problem is: When I stream the video, I just get the video being played in the browser, as a direct link to some downloaded video, not the renderized page with some data(video title and path).
I wanna render the page and then run the video.
When I render, I receive the error: "Can't set headers after they're sent".
My code:
const express = require('express')
const multer = require('multer')
const moment = require('moment')
const uuidv4 = require('uuid/v4');
const bodyParser = require('body-parser')
const fs = require('fs')
const videoLib = require('node-video-lib')
const app = express()
const db = require('./db')
let Video = require('./models/videoModel')
//***** STAND LIBRARIES CONFIGURATION **********//
app.use(bodyParser.urlencoded({extended:true}))
app.use(bodyParser.json())
app.set('views', 'views')
app.set('view engine', 'ejs')
app.set(db)
//***** MULTER CONFIGURATION ***************//
let storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, './uploads')
},
filename: function(req, file, cb){
let mime = file.mimetype.split('/')[1]
let uuid = uuidv4()
cb(null, uuid + "." + mime)
}
})
function fileFilter(req, file, cb){
const extension = file.mimetype.split('/')[0];
if(extension !== 'video'){
return cb(new Error('Something went wrong. Wrong file format'), false);
}
cb(null, true);
};
var upload = multer({storage:storage, fileFilter: fileFilter})
const uploadHandler = upload.single('video')
function uploadVideo(req, res, next){
uploadHandler(req, res, next, function(err){
if(req.fileValidationError){
res.send('Error when upload')
}
console.log(req.file.filename)
next()
})
}
//******************************************//
function newVideo(req, res){
let videoParams = {title: req.body.title, path: req.file.filename}
Video.create(videoParams, function(err, result){
if(err){
console.log(err)
}
else{
console.log("Video salvo com sucesso")
console.log(result)
res.send(result )
}
})
}
app.get('/videos/:id', function(req, res){
let path = req.params.id
Video.find({path:path}, function(err, result){
if(err){
console.log(err);
}
else{
if (true) {
console.log("The url is:" + req.url);
const path = req.url.split('/')[2]
console.log("Path:" + path);
var file = `./uploads/${path}`
var range = req.headers.range;
fs.stat(file, function(err, stats) {
var total = stats.size;
if(range){
console.log('RANGE: ' + range);
var positions = range.replace(/bytes=/, "").split("-");
var start = parseInt(positions[0], 10);
var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
var chunksize = (end - start) + 1;
console.log(req.url, start, end);
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
fs.createReadStream(file, { start: start, end: end }).pipe(res);
} else {
res.writeHead(200, { 'Content-Length': total, 'Content-Type': 'video/mp4' });
fs.createReadStream(file).pipe(res);
res.render('videos', {videoData:result})//Erro: can't set header after they're sent
}
});
} else {
console.log(req.url + ' (static)');
next();
}
}
})
})
app.get('/', function(req, res){
Video.find({}, function(err, result){
if(err){
console.log(err);
}
else{
console.log();
res.render('home', {videoData:result})
}
})
})
app.post('/upload', uploadVideo, newVideo)
app.listen(3000, ()=>{
console.log("Server running on port 3000")
})
You can't use both
res.writeHead();
and
res.render();
Read more: Error: Can't set headers after they are sent to the client

req.params undefined in module

I have an working api for serving images in a route in my server.js and want to abstract it to a separate module.
before:
app.get('/api/image/:filename', function(req, res){
var resourcePath = 'uploads/public/projectnumber/issues/small/' + req.params.filename + '.png';
console.log(resourcePath)
if(fs.existsSync(resourcePath)) {
var file = fs.readFileSync(resourcePath);
res.writeHead(200, 'Content-Type:application/pdf:image/png');
res.end(file,'binary');
}
else {
res.send(400, 'No image found');
}
})
I want something like this:
var ImageRouter = require('./routes/imageRouter');
app.use('/api/image/:filename', ImageRouter);
and I've tried writing it like this in my imageRouter.js file:
var express = require('express');
var fs = require('fs');
var router = express.Router();
router.use(function(req, res, next) {
var resourcePath = 'public/images/' + req.params.filename + '.png';
if(fs.existsSync(resourcePath)) {
var file = fs.readFileSync(resourcePath);
res.writeHead(200, 'Content-Type:application/pdf:image/png');
res.end(file,'binary');
}
else {
res.send(400, 'No image found');
}
next();
});
module.exports = router;
But req.params.filename is undefined. Where have I gone wrong?
Thanks!
You should use get() on your imageRouter.js Router and prefix it on your main app.
use() is for middlewares.
Here is imageRouter.js:
var router = require('express').Router();
var fs = require('fs');
router.get('/:filename', function(req, res) {
var resourcePath = 'public/images/' + req.params.filename + '.png';
if(fs.existsSync(resourcePath)) {
var file = fs.readFileSync(resourcePath);
res.writeHead(200, 'Content-Type:application/pdf:image/png');
res.end(file,'binary');
}
else {
res.send(400, 'No image found');
}
});
module.exports = router;
And your server.js:
var express = require('express');
var app = express();
var ImageRouter = require('./routes/imageRouter');
app.use('/api/image', ImageRouter);

how to upload and read a file with nodejs / express

there are all kinds of posts about this, but I'm still not getting it.
I want to upload a *.csv and read and process its contents.
my jade file is this
//views/import.jade
extends layout
block content
h1= title
form(action="/import", method="post", enctype="multipart/form-data")
input(type="file", name="ufile")
input(type="submit", name="Upload")
--
I changed the code, but req.files is undefined
//routes/index.js
/* import page. */
router.get('/blah', function(req, res, next) {
res.render('import', { title: 'Import Data' });
});
router.post('/import', function(req, res) {
console.log(req.files);
});
module.exports = router;
Convert the uploaded file in to string, using
toString('utf8')
you can than make any operation on string like convert it to json using csvtojson package
Here is the sample code for uploading csv and than convert to json-
/* csv to json */
const express = require("express"),
app = express(),
upload = require("express-fileupload"),
csvtojson = require("csvtojson");
let csvData = "test";
app.use(upload());
app.get("/", (req, res, next) => {
res.sendFile(__dirname + "/index.html");
});
app.post("/file", (req, res) => {
/** convert req buffer into csv string ,
* "csvfile" is the name of my file given at name attribute in input tag */
csvData = req.files.csvfile.data.toString('utf8');
return csvtojson().fromString(csvData).then(json =>
{return res.status(201).json({csv:csvData, json:json})})
});
app.listen(process.env.PORT || 4000, function(){
console.log('Your node js server is running');
});
working example- csvjsonapi
Hope this solves your question, this is my method to multiple upload file:
Nodejs :
router.post('/upload', function(req , res) {
var multiparty = require('multiparty');
var form = new multiparty.Form();
var fs = require('fs');
form.parse(req, function(err, fields, files) {
var imgArray = files.imatges;
for (var i = 0; i < imgArray.length; i++) {
var newPath = './public/uploads/'+fields.imgName+'/';
var singleImg = imgArray[i];
newPath+= singleImg.originalFilename;
readAndWriteFile(singleImg, newPath);
}
res.send("File uploaded to: " + newPath);
});
function readAndWriteFile(singleImg, newPath) {
fs.readFile(singleImg.path , function(err,data) {
fs.writeFile(newPath,data, function(err) {
if (err) console.log('ERRRRRR!! :'+err);
console.log('Fitxer: '+singleImg.originalFilename +' - '+ newPath);
})
})
}
})
Make sure your form tag has enctype="multipart/form-data" attribute.
I hope this gives you a hand ;)

Resources