angular file upload+sails skipper upload no file - angularjs

I'm using angularJS for my frontend and sails.js/expressjs for my backend. I'm implementing a file upload function using ng-file-upload, and strangely the file never seem to upload to the server successfully... this is my angularJS code:
$scope.$watch('data.chosenImageFile', function() {
if ($scope.data.chosenImageFile) {
console.log($scope.data.chosenImageFile);
$scope.upload = $upload.upload({
url: '/upload_user_avatar',
method: 'POST',
file: $scope.data.chosenImageFile
}).progress(function(evt) {
console.log('progress: ' + parseInt(100.0 * evt.loaded / evt.total));
}).success(function(data, status, headers, config) {
console.log(data);
});
}
});
And this is my sails.js code:
uploadUserAvatar: function(req, res) {
req.file('avatar').upload(function(err, files) {
if (err) return res.send(500, err);
return res.json({
message: files.length + ' file(s) uploaded successfully!',
files: files
});
});
},
And I always get the following response from server:
Object {message: "0 file(s) uploaded successfully!", files: Array[0]}
When I check the corresponding server upload destination folder, there's nothing.... anyone know why or could provide some help? Will really appreciate it!

Ok this question isn't a really smart one, I figured out where the problem is: the default fileFormDataName for ng-file-upload is "file", since I'm using req.file('avatar') on the server side, I should really add the following setting option in my angular code:
fileFormDataName: 'avatar',
which makes it look like so:
$scope.$watch('data.chosenImageFile', function() {
if ($scope.data.chosenImageFile) {
console.log($scope.data.chosenImageFile);
$scope.upload = $upload.upload({
url: '/upload_user_avatar',
method: 'POST',
fileFormDataName: 'avatar',
file: $scope.data.chosenImageFile
}).progress(function(evt) {
console.log('progress: ' + parseInt(100.0 * evt.loaded / evt.total));
}).success(function(data, status, headers, config) {
console.log(data);
});
}
});
UPDATE
According to #Anupam Bhaskar's request, I've also added my HTML code for a file upload dropzone below:
<div ng-file-drop ng-if="!data.isUploading" ng-model="data.chosenImageFile" class="avatar-dropzone pull-left" drag-over-class="upload-dropzone" ng-file-change="avatarUpload.fileSelected('/upload_user_avatar', data.user, data)" multiple="false" allow-dir="true" accept="*">
<div class="text-center upload-sign">+</div>
</div>

Related

Angular and cloudinary integration error?

I am using clodinary - angular app in github mentioned below
https://github.com/cloudinary/cloudinary_angular
But in that app, it shows only uploading image with image preset.But I need to upload image with API key.I changed my code as
In my app.js
app.config(['cloudinaryProvider' , function (cloudinaryProvider) {
cloudinaryProvider
.set("cloud_name", "********")
.set("api_key", "**********")
.set("api_secret", "****************");
//.set("upload_preset", "*******");
}
]);
I commented upload preset and changed 'unsigned' to 'signed' in cloudinary dashboard.
In my service
promise = $upload.upload({
url: "https://api.cloudinary.com/v1_1/" + cloudinary.config().cloud_name + "/upload",
data: {
api_key: cloudinary.config().api_key,
api_secret: cloudinary.config().api_secret,
tags: 'myphotoalbum',
context: 'photo=' + title,
file: file
}
}).progress(function (e) {})
.success(function (data, status, headers, config) {
return data;
}).error(function (data, status, headers, config) {
return data;
});
But it shows "Bad Request Error".How can I fix this issue.Please help me and thanks in advance.

NodeJS & Angular Image upload

Tried lot of available Internet tutorials, but I still can't make it functional. I use multer module in NodeJS and ng-file-upload in AngularJS. I made two helpers with multer settings( because I have two scenarios and both uploads must go to different folders). Backend files are in APP/APP_BACK/ folder, so in destination path I go back one folder and enter APP_FRONT/images/header. Here is one helper snippet (/helpers/uploadHeader.js):
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, '../APP_FRONT/images/header/');
},
filename: function (req, file, callback) {
var ext = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
callback(null, file.fieldname + '-' + '.' + ext);
}
});
var upload = multer(
{storage: storage}
);
var helper = {
upload: upload
};
module.exports = helper;
Here is router file:
var headerHelper= require('../helpers/uploadHeader');
router.post('/header', headerHelper.upload.single('header'), function(req, res, next) {
headerHelper.upload(req, res, function(err){
if(err){
res.status(400).send(err);
console.log(err);
return;
}
res.status(200).send({ code:200, message:'Header upload successful!' });
});
});
"header" would be name of input form or key value in Postman.
In Angular, I injected 'ngFileUpload' module in app, and injected 'Upload' service into desired controller and used it inside uploadHeader() function which is bound on button inside form on clientside:
$scope.uploadHeader = function (file) {
Upload.upload({
url: 'http://localhost:3003/upload/header',
method: 'POST',
file: file
}).then(function (response) {
console.log('Success ' + response.config.data.file.name + 'uploaded. Response: ' + response.data);
}, function (error) {
console.log('Error status: ' + error.status);
}, function (evt) {
var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
console.log('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
});
I tried with Postman:
Postman request SS
And get this error:
"Error: ENOENT: no such file or directory, open 'c:\Users\Username\Desktop\APP\APP_FRONT\images\header\header.jpg'"
When I try from clientside, I get these errors:
"Error: Unexpected field at makeError "
and
"TypeError: dbg is undefined"
I already consulted Google, tried some of tutorials but got stuck on this.
In your router, you are telling multer to look for an object called "header" in the mulitpart form data. Your angularJS code is adding it as an object called 'file'.
If you change the line in your router from:
router.post('/header', headerHelper.upload.single(**'header'**), function(req, res, next) {
//.....
}
to:
router.post('/header', headerHelper.upload.single(**'file'**), function(req, res, next) {
//....
}
It should do the trick.
EDIT: solution found
Actually, it was problem in filename function in multer's storate settings. In above post, I appended datetimestamp and file extension to fieldname:
filename: function (req, file, callback) {
var datetimestamp = moment().format('DD-MM-YY_HH:mm:ss');
var filename = file.originalname;
var ext = filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
callback(null, file.fieldname + '-' + datetimestamp + '.' + ext);
}
For some reason, it couldn't finish upload and I got error.
I changed filename function to return only file's originalname :
filename: function (req, file, callback) {
callback(null, file.originalname);
}
and now everything is OK. But now, question is, why custom filename doesn't work?

------WebKitFormBoundary being added by AngularJS app

I built a Ruby/Sinatra backend for an angularjs app. I wrote a POST call to parse and upload a file from the request body to AWS S3. Now when I use Postman to upload a file. It works completely fine, the file gets uploaded and I can view it on S3. But the problem is that when I try to upload a file using the angular app, it adds the following to the file cause of which the file gets corrupted and a pdf file opens up as a text file within the browser.
------WebKitFormBoundaryuRzuSgC6oXxEgwa1
Content-Disposition: form-data; name="file"; filename="Application Form.pdf"
Content-Type: application/pdf
***FILE DATA HERE***
------WebKitFormBoundaryuRzuSgC6oXxEgwa1--
Can someone help me to either parse this data properly in the ruby or help me to avoid adding this extra code from the angular app.
This is the angular code to upload the file
$scope.uploadFiles = function(files, errFiles) {
$scope.all_files.push(files);
console.log($scope.all_files[0]);
$scope.files = files;
$scope.errFiles = errFiles;
angular.forEach(files, function(file) {
file.upload = Upload.upload({
url: 'http://api.company.com/upload',
data: {file: file}
});
file.upload.then(function (response) {
$timeout(function () {
file.result = response.data;
});
}, function (response) {
if (response.status > 0)
$scope.errorMsg = response.status + ': ' + response.data;
}, function (evt) {
file.progress = Math.min(100, parseInt(100.0 *
evt.loaded / evt.total));
});
});
};
And the following is the code in Ruby to parse and upload the file
post '/upload' do
request.body.rewind
body = request.body.read
res(200, {url: saveFile(body)})
end
def saveFile(body)
name = "random string here"
s3 = Aws::S3::Resource.new(region:'ap-southeast-1')
obj = s3.bucket('company-files').object(name)
obj.put(body: body, acl:'public-read')
saved_url = obj.public_url
return saved_url
end
You may need to manually set the Content-Type header to force your browser to use this upload mechanism, probably at this point:
file.upload = Upload.upload({
url: 'http://api.company.com/upload',
data: {file: file}
});
I don't know what's Upload object, so I can't say how to do it

Angularjs - downloading a file in a specific location

here is the situation.
I have an angular app that need to be used via a machine on wich you can put an USB key.
Several exports are possible from the corresponding backend and thoses exports (pdf, csv or rtf) need to be downloaded directly on the key, without asking the user.
Furthermore I need to be able to detect if the key is not present and show an error.
I don't think that it is doable using only angular with chromium.
I was thinking of making a local nodejs server on each machine that could access the filesystem for that. It works when using postman with form-data, but I don't know how I can pass a file donwloaded in angular to the nodejs server as a formdata, I keep getting incorrect pdf files.
TLDR :
I need to be able to have a chain like this :
get file from backend in angular
post a request to local (nodejs) server with the downloaded file
receive the file in nodejs to save it on disk
I am open to other ideas if this one doesn't work, as long as I can download this file I am happy.
current nodejs code, that works when i post the file using postman :
router.post('/save', function(req, res, next) {
console.log('savexvbxc');
var fstream;
//test if USB key is available
fs.stat(basePath, function(err, stats) {
if (err) {
console.log('error, key not present');
res.send(412, 'FAILURE');
}
var filename = basePath + 'toti.pdf';
console.log('filename is ' + filename);
if (req.busboy) {
console.log('busboy loaded');
req.busboy.on('file', function(fieldName, fileStream, fileName, encoding, mimeType) {
console.log('Saving: ' + filename + ' ' + fileName);
fstream = fs.createWriteStream(filename);
fileStream.pipe(fstream);
fstream.on('close', function() {
console.log('successfully saved ' + filename);
res.status(200).send('SUCCESS');
});
fstream.on('error', function(error) {
console.log('failed saved ' + filename);
console.log(error);
res.send(500, 'FAILURE');
});
});
req.busboy.on('error', function(error) {
console.log('failed saved ' + filename);
console.log(error);
res.send(500, 'FAILURE');
});
return req.pipe(req.busboy);
} else {
console.log('error, busboy not loaded');
res.send(500, 'FAILURE');
}
});
});
current angular code that do not work:
var dlReq = {
method: 'GET',
url: '/fep/documents/TVFI_FEP_0015_SFS_Specifications_Fonctionnelles_Detaillees_V00.9.pdf',
headers: {
'Content-Type': 'application/pdf',
'Accept': 'http://localhost:4000/fep/documents/TVFI_FEP_0015_SFS_Specifications_Fonctionnelles_Detaillees_V00.9.pdf'
},
responseType: 'arraybuffer'
};
$http(dlReq).then(function(data, status, headers, config) {
console.log(resp);
var file = new Blob([(resp)], {type: 'application/pdf'});
var formdata = new FormData();
formdata.append('file', file);
var request = {
method: 'POST',
url: 'http://localhost:4080/save',
data: formdata,
headers: {
'Content-Type': undefined,
'Accept': '*/*'
}
};
// SEND THE FILES.
$http(request)
.success(function(d) {
console.log('ok', d);
})
.error(function() {
console.log('fail');
});
});
Thank you

How do I send an image file for download from Node backend to Angular frontend?

I have an app with an Express backend, and angular frontend. I am trying to create a file download link for image files, but I am running into problems sending the file from express to angular. My angular looks like this...
scope.download = function(file){
http({method:'GET', url:'/get_download/' + file.id}).
success(function(data, status, headers, config) {
var element = angular.element('<a/>');
element.attr({
href: 'data:attachment;charset=utf-8,' + encodeURIComponent(data),
target: '_self',
download: file.name
})[0].click();
}).
error(function(data, status, headers, config) {
console.log("THERE WAS AN ERROR");
});
}
I have tried several different things on the express side each of which are producing different errors.
First I tried the following...
res.download("my_file_path", "my_file_name", function (err) {
if (err) {
console.log("ERROR");
console.log(err);
}
});
And got this error...
path.js:360
throw new TypeError('Arguments to path.join must be strings');
^
TypeError: Arguments to path.join must be strings
Then I tried...
fs.readFile("my_file_path", function(err, data) {
res.writeHead(200, { 'Content-disposition': 'attachment' });
res.end(data);
});
Which downloaded the file, but it got corrupted along the way, and would not open.
Any suggestions would be appreciated.

Resources