I would like to send a file to my Node.js application, but it seems that the application receives nothing. I'm not sure what to do. How am I supposed to check If I have sent the file, and if I am receiving it in req?
<form>
<input type = "file" file-model="files" multiple/>
<button class="md-primary md-button md-cyan-theme md-ink-ripple" ng-click = "vm.uploadFile()">upload me</button>
</form>
This is my controller:
function uploadFile() {
console.log("Load");
var fd = new FormData();
console.log($scope.files) // FileList {0: File, Length: 1}
angular.forEach($scope.files, function (file) {
fd.append('file', file);
});
console.log(fd); // FormData {} (Empty?)
$http.post('http://localhost:8090/file-upload'), {
headers: {'Content-Type': undefined },
files: fd
}).success(function (d) {
console.log(d);
});
}
This is my directive:
.directive('fileMode', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.bind('change', function () {
$parse(attrs.fileModel).assign(scope, elemtn[0].files);
scope.$apply();
});
}
};
}])
Here is my Express app:
app.post('/file-upload', function (req, res, next) {
console.log("Sent!");
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, cb) {
cb(null, file.fieldname);
}
});
var upload = multer({ storage : Storage }).array('userPhoto', 2);
upload(req, res, function (err) {
console.log(req.body.data.files);
if (err) return res.end("Error uploading file.");
res.end("File is uploaded.");
})
})
Thank you for the help.
The field names are not the same in web-form and in multer configuration:
var upload = multer({ storage : storage }).array('file',2);
Hope this will work!
var express = require('express'),
app = express(),
bodyParser = require('body-parser'),
multer = require('multer');
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "http://localhost");
res.header(
"Access-Control-Allow-Origin",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
app.use(express.static('../client'));
app.use(bodyParser.json());
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var split = file.originalname.split('.');
cb(null, file.fieldname + "-" + Date.now() + "." + split[split.length - 1]);
}
});
var upload = multer({ storage : storage }).single('file');
app.post('/upload', function (req, res) {
upload(req, res, function (err) {
if (err) res.json({ error_code: 1, err_desc: err });
res.json({error_code: 0, err_desc: null });
})
})
app.listen('3000', function () {
console.log("Running on 3000");
})
Related
I have written this code to send a file using a port from NodeJS server to Django server using multer and Custom Directives from AngularJS
const multerConf = {
storage:multer.diskStorage({
filename:function(req,file,next){
const etx = file.mimeType.split('/')[1];
next(null,file,fieldname+'-'+Date.now()+'-'+ext);
}
})
};
var newName = '';
app.post('/upload', multer(multerConf).single('file'), function(req, res){
if(req.files.file){
req.body.file = req.files.filename;
var file = req.files.file;
var filename = req.files.file.name;
newName = './upload/'+Date.now()+filename;
file.mv(newName,function(err){
if(err){
console.log(err);
res.send("Upload failed");
}else{
var fileUrl='./upload/'+filename;
console.log(fileUrl);
}
});
const options = {
url: 'http://localhost:8000/myAssignmentApp/a_n_d',
method: 'GET',
headers: {
'Accept': 'application/json',
'Accept-Charset': 'utf-8'
}
};
request(options, function(err, res) {
});
}
});
The following code is for the port.
server.on('request', (req, res) => {
fs.readFile(newName, (err, data) => {
if (err) throw err;
res.end(data);
});
});
server.listen(6000);
Is there any other more efficient method to do the same?
I have a form with text-fields & drop-downs.
I am using Node.js , Angular js, Express, MongoDb.
I want to post data along with image(s).
I want to store image in folder, without any base/binary conversion, and image path should be stored in mongoDb.
How can I achieve this?
HTML FILE
<div class="form-group">
<label class="col-md-4">Profile Photo</label>
<input type="file" class="form-control"
formControlName="s_profile"
#s_profile ng2FileSelect
[uploader]="uploader"
(change)="uploader.uploadAll()" />
</div>
<div class="form-group">
<button (click)="addfile()"
[disabled]="angForm.pristine || angForm.invalid"
class="btn btn-primary">Upload</button>
</div>
COMPONENT FILE
const URL = 'http://localhost:4000/api/upload';
public uploader: FileUploader = new FileUploader({url: URL, itemAlias: 'photo'});
ngOnInit() {
this.uploader.onAfterAddingFile = (file) => { file.withCredentials = false; };
this.uploader.onCompleteItem = (item: any, response: any, status: any, headers: any) => {
//console.log('ImageUpload:uploaded:', item, status, response);
console.log(response);
this.profilPhotos = response;
};
}
addfile(){
this.ss.addStudent(this.profilPhotos);
}
SERVICE FILE
uri = 'http://localhost:4000/business';
addBusiness(uploadImages) {
const obj = {uploadImages: uploadImages};
this.http.post(`${this.uri}/add`, obj)
.subscribe(res => console.log('Done'));
}
SERVER FILE
const DIR = '../src/assets/upload';
let storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, DIR);
},
filename: (req, file, cb) => {
console.log(file);
cb(null, file.originalname);
}
});
let upload = multer({storage: storage});
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
res.setHeader('Access-Control-Allow-Methods', 'POST, GET');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.post('/api/upload',upload.single('angular'), function (req, res) {
if (!req.file) {
console.log("No file received");
return res.send({
success: false
});
} else {
console.log('file received');
return res.send(req.file.filename)
}
});
ROUTER FILE
const path = require('path');
const fs = require('fs');
const express = require('express');
const multer = require('multer');
const bodyParser = require('body-parser');
const app = express();
const router = express.Router();
const DIR = './uploads';
let storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, DIR);
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now() + '.' + path.extname(file.originalname));
}
});
let upload = multer({storage: storage});
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:4200');
res.setHeader('Access-Control-Allow-Methods', 'POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
app.post('/api/upload',upload.single('photo'), function (req, res) {
if (!req.file) {
return res.send({
success: false
});
} else {
return res.send({
return res.send(req.file.filename)
})
}
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, function () {
console.log('Node.js server is running on port ' + PORT);
});
You can use the simple/lightweight ng-file-upload directive. It supports drag&drop.
<div ng-controller="MyCtrl">
<input type="file" ngf-select="onFileSelect($files)" multiple>
</div>
JS:
angular.module('myApp', ['ngFileUpload']);
var MyCtrl = [ '$scope', 'Upload', function($scope, Upload) {
$scope.onFileSelect = function($files) {
Upload.upload({
url: 'api/upload',
method: 'POST',
file: $files,
}).progress(function(e) {
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
}];
You can use formidable for parsing form data, especially file uploads. Read more here
app.post('/api/upload', function(req, res) {
var form = new formidable.IncomingForm();
form.multiples = true;
form.uploadDir = path.join(__dirname, '../../public/images');
form.on('file', function(field, file) {
//copy file to new path
fs.renameSync(file.path, path.join(form.uploadDir, file.name));
var Image = path.join(form.uploadDir, file.name);
//save new path to mongodb
db.collection('images').insert({
imagePath: Image
}, function(err, result) {
// do your stuff
})
});
})
This is just my suggestion. You should learn more and do what you expect. Hope it help.
Front-End:
HTML:
<input type="file" nv-file-select uploader="vm.uploader"
id="fileUpload" ng-model="vm.schema.file"/>Browse
Controller:
angular
.module('myApp')
.controller('myController', myController);
myController.$inject = ['FileUploader'];
function EditSchemaBasicController(FileUploader) {
vm.uploader = new FileUploader({
url: "https://localhost:3000/api/file", //your api URL
queueLimit: 10,
onAfterAddingFile: function(item) {
//before upload logic will go here like file size and extension handling
item.upload();
},
onCompleteItem: function(item, response){
//on complete
console.log('Uploaded File: ' + response.file);
},
onErrorItem: function(item, response) {
//error handling
}
});
}
Back-End:
'use strict'
var express = require('express');
var router = express.Router();
var fs = require('fs-extra');
//Post file.. i used busboy to upload the file
router.post('/', function(req, res, next) {
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
filename = decodeURI(filename);
//Path where file will be uploaded
var fstream = fs.createWriteStream('API/Images' + filename);
file.pipe(fstream);
fstream.on('close', function () {
res.status(201).json({file: filename});
});
});
});
module.exports = router;
I am using Nodejs + Multer +angularjs for uploading files on the server.
i have a simple HTML file:
<form action="/multer" method="post" enctype="multipart/form-data">
<input type="file" id="photo" name="photo"/>
<button id="Button1">Upload</button>
</form>
Nodejs part:
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
app.post('/multer', upload.single('photo'), function (req, res) {
res.end("File uploaded.");
});
this works perfectly and the file is successfully uploaded.
but this redirect me to "/multer" after uploading the file (because of the form element).
How do i stay on the same page??..possibly using angularjs
so i tried this:
making a HTML angular file:
<section data-ng-controller="myCtrl">
<input type="file" id="photo" name="photo"/>
<button id="Button1" ng-click="f()">Upload</button>
</section>
and a Angularjs controller:
angular.module('users').controller('myCtrl',[$scope,function($scope){
$scope.f=function(){
var photo = document.getElementById('photo');
var file = photo.files[0];
if (file) {
//code to make a post request with a file object for uploading?????
//something like..
//$http.post('/multer', file).success(function(response) {
//console.log("success");
//});
}
}
}]);
CAN SOMEONE HELP ME WITH THE CODE FOR MAKING A POST REQUEST WITH A FILE OBJECT FOR UPLOADING USING MULTER FROM ANGULARJS CONTROLLER ?
thanks
Angularjs directive:
angular.module('users').directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};
}]);
Angular html file:
<input type="file" file-model="myFile"/><br><br>
<button ng-click="uploadFile()">Upload</button>
Angularjs Controller:
$scope.uploadFile = function(){
var file = $scope.myFile;
var uploadUrl = "/multer";
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl,fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
console.log("success!!");
})
.error(function(){
console.log("error!!");
});
};
Nodejs server route file:
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname+ '-' + Date.now()+'.jpg')
}
});
var upload = multer({ storage: storage });
app.post('/multer', upload.single('file'));
Enjoy!
The following code produces an image in the desired location, however, the image is not being named correctly.
routes.js
var upload = multer({
dest: './client/shared/assets/images/logos',
rename: function (fieldname, filename, req, res) {
console.log('Rename YO!')
console.log(fieldname)
console.log(filename)
console.log(req)
return 'test' + '-'+Date.now();
}
});
app.post('/uploads/logo',upload.single('file'), function(req, res){
console.log('Upload photo yo!')
console.log(req.body) // form fields
console.log(req.file) // form files
res.status(204).end()
});
create.controller.js
$scope.saveLogo = function(file) {
console.log(file);
file.upload = Upload.upload({
url: '/uploads/logo',
method: 'POST',
fields: {
name: $scope.item.name,
subdomain: $scope.item.subdomain
}
});
file.upload.then(function (_res) {
console.log(_res)
file.result = _res.data;
}, function (_res) {
console.log(_res)
if (_res.status > 0)
$scope.errorMsg = _res.status + ': ' + _res.data;
});
file.upload.progress(function (evt) {
// Math.min is to fix IE which reports 200% sometimes
file.progress = Math.min(100, parseInt(100.0 * evt.loaded / evt.total));
});
};
I don't know what I am missing here. I am trying to limit the multer functionality to a specific post action, could that be it?
Thanks in advance
Solved with this little tidbit:
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '/tmp/my-uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload = multer({ storage: storage })
The approach has changed to the above method since the last release
I am trying to upload multipart/form-data for a simple MEAN stack application. When putting everything in one file and running it it works fine.
Server.js
var express = require('express');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/');
},
filename: function (req, file, cb) {
switch(file.mimetype) {
case 'image/jpg' :
case 'image/jpeg':
case 'image/gif':
var extension = file.mimetype.split("/");
extension = extension[extension.length-1];
break
case 'video/quicktime':
var extension = 'mov';
break
case 'video/mp4':
var extension = 'mp4';
break
default:
var extension = 'jpeg';
}
cb(null, file.fieldname + '-' + Date.now() + "." + extension);
}
});
var upload = multer({ storage: storage });
var path = require('path');
var app = express();
var segmentUpload = upload.fields([{ name: 'segmentVideo', maxCount: 1}, { name: 'segmentStill', maxCount: 1}, { name: 'segmentGif', maxCount: 1}])
app.post('/photos/upload', segmentUpload, function (req, res, next) {
console.log(req);
console.log(req.files['segmentVideo'][0]);
console.log(req.files['segmentStill'][0]);
console.log(req.files['segmentGif'][0]);
console.log(req.body.title);
});
app.get('/', function(req, res) {
res.sendfile('./index.html');
});
app.listen(8080);
console.log("App listening on port 8080");
index.html
<body>
<form action="/photos/upload" method="post" enctype="multipart/form-data">
title: <input type="text" name="title"> <br><br>
Select video to upload:
<input type="file" name="segmentVideo" id="fileToUpload"> <br><br>
Select jpeg to upload:
<input type="file" name="segmentStill" id="fileToUpload"><br><br>
Select gif to upload:
<input type="file" name="segmentGif" id="fileToUpload"><br><br>
<input type="submit" value="Upload Image" name="submit">
</form>
But when I try to integrate multer into my node routing I cannot get my app to accept the multipart/form-data.
app/routes.js
var Video = require('./models/video');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/');
},
filename: function (req, file, cb) {
switch(file.mimetype) {
case 'image/jpg' :
case 'image/jpeg':
case 'image/gif':
var extension = file.mimetype.split("/");
extension = extension[extension.length-1];
break
case 'video/quicktime':
var extension = 'mov';
break
case 'video/mp4':
var extension = 'mp4';
break
default:
var extension = 'jpeg';
}
console.log("new extension: " + extension);
cb(null, file.fieldname + '-' + Date.now() + "." + extension);
}
});
var upload = multer({ storage: storage });
module.exports = function(app) {
// api --------------------------------------
// get all todos
app.get('/api/videos', function(req,res){
// use mongoose to get all todos in the database
Video.find(function(err, videos){
// if there is an error, send the error
if (err)
res.send(err);
res.json(videos);
});
});
var segmentUpload = upload.fields([{ name: 'segmentVideo', maxCount: 1}, { name: 'segmentStill', maxCount: 1}, { name: 'segmentGif', maxCount: 1}])
app.post('/api/videos', segmentUpload, function(req, res){
// create a video
Video.create({
title : req.body.title,
description : req.body.description,
category : req.body.category,
day : req.body.day,
videoUrl : req.body.videoUrl,
stillUrl : req.body.stillUrl,
gifUrl : req.body.gifUrl,
airReady : false
}, function(err, video) {
if (err)
res.send(err)
// get and return all the todos after you create another
Video.find(function(err, videos){
if (err)
res.send(err)
res.json(videos);
});
});
});
// delete a todo
app.delete('/api/videos/:video_id', function(req,res){
Video.remove({
_id : req.params.video_id
}, function(err, video) {
if (err)
res.send(err);
// get and return all the todos after you delete one
Video.find(function(err, videos) {
if (err)
res.send(err)
res.json(videos);
});
});
});
// edit a todo
app.put('/api/videos/:video_id', function(req,res){
Video.findByIdAndUpdate(req.params.video_id,
{ $set: { title: req.body.title
}},
function(err, video){
if (err)
res.send(err)
// get and return all todos after edit
Video.find(function(err, videos){
if (err)
res.send(err)
res.json(videos);
});
});
});
// find -------------------------------------------------------------
app.get('*', function(req, res) {
res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
};
I receive an error:
TypeError: Cannot read property 'title' of undefined
This is my first post to stack overflow, but I appreciate all of the support!
The problem might be due to use are sending the multipart/form-data but you are not converting it to json and you are using json for retrieving the data.
Use body-parser
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());