Converting php file upload end point to node.js/express - angularjs

Sorry i havent used file uploads in node.js before
Currently i cam using angular service that uses FormData and submits a $http post request to php and there it is uploaded with move_uploaded_file() that is working fine
Angular .js code
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' + JSON.stringify(file));
var uploadUrl = "upload.php";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
html
<input type="file" file-model="myFile"/>
<button ng-click="uploadFile()">upload me</button>
How can i get this into node.js express route?
i have read other questions on stack overflow but i cant quite get it that were will the data be going in res.body? or res.files and how to finnaly upload them
my undesrtandings about it is that it will be something like this
routes.post("/upload",function(req,res,next){
console.log(req.Files);
console.log(req.body);
});

Related

Angular - pass scope to service and set value

I cannot pass/set the value to the text-area outside the controller.
I am uploading an excel and regarding the upload status I want to set some data to a text-area.
This is my code so far:
app.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl, commentArea){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
/* commentArea.append('This is not working');
commentArea = 'This is not working';
$scope.outputImportObject = 'This is not working';
*/
alert('The file was succesfully uploaded!');
})
.error(function(){
alert('There was an error while inserting the file!');
});
}
}]);
app.controller('UploadCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
$scope.outputImportObject = 'This is working';
var file = $scope.myFile;
var commentArea = $scope.outputImportObject;
fileUpload.uploadFileToUrl(file, ws_url+'upload_excel.php',commentArea);
};
}]);
This typically seems a case where you should be using promises.
From your services you should return a promise and based on their resolution or rejection, you should bind the variable on controller.
your service should look something like:
app.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl, commentArea){
var fd = new FormData();
fd.append('file', file);
return
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
}
}]);
Since, http itself return a promise, you can directly return it, instead of making your custom promise.
and your controller should be like:
app.controller('UploadCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
$scope.outputImportObject = 'This is working';
var file = $scope.myFile;
var commentArea = $scope.outputImportObject;
fileUpload.uploadFileToUrl(file, ws_url+'upload_excel.php',commentArea)
.then(doThisOnSuccess, doThisOnFailure);
function doThisOnSuccess(){
code for binding to text area should go here
}
function doThisOnFailure(){
}
};
}]);

angular file upload with ng-file-upload

I am uploading image file using ng-file-upload for image upload. using the example given, I encountered access-control header error.
vm.uploadPic = function(file) {
file.upload = Upload.upload({
url: 'http://localhost:8000/api/v1/quotes/quoteitem/image/upload',
data: {quote_item_id: vm.quote_item_id, filename: file}
});
}
This gives error
XMLHttpRequest cannot load http://localhost:8000/api/v1/quotes/quoteitem/image/upload. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
I don't need any header request while uploading image in postman so, I removed header.
vm.uploadPic = function(file) {
file.upload = Upload.upload({
url: domain+'/api/v1/quotes/quoteitem/image/upload',
data: {quote_item_id: vm.quote_item_id, filename: file},
transformRequest: function(data, headersGetter) {
var headers = headersGetter();
headers['Content-type']=undefined;
return headers;
}
});
}
This gives
TypeError: data.hasOwnProperty is not a function
at ng-file-upload.js:310
at angular.js:10484
at forEach (angular.js:322)
at transformData (angular.js:10483)
at $get.serverRequest (angular.js:11211)
at processQueue (angular.js:15961)
at angular.js:15977
at Scope.$get.Scope.$eval (angular.js:17229)
at Scope.$get.Scope.$digest (angular.js:17045)
at Scope.$get.Scope.$apply (angular.js:17337)
I am stuck in this for quite a time now. I have tested in server side and it works fine in postman. Any help would be wonderful.
The problem is that you are uploading from the site at port 3000 to an endpoint at port 8000. These are considered separate origins, so the browser's security features are kicking in. You either need to get them on the same origin, or add the 'Access-Control-Allow-Origin' header to the server-side response of the upload endpoint.
Please try these one
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(data){
alert("success");
})
.error(function(data){
alert("error");
});
};
}]);
myApp.controller('fupController', ['$scope', 'fileUpload', '$http', function($scope, fileUpload, $http){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is '+ file );
console.dir(file);
var uploadUrl = 'http://localhost:8000/api/v1/quotes/quoteitem/image/upload';
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
Try this
<form method="post" enctype="multipart/form-data" ng-controller="commentCtrl" name="form">
<img src="source/assets/images/icons/icofileattached.png" class="attachmentpng-height" ngf-select="uploadFiles($file)" ng-model="files"/>
<md-button type="submit" class="md-raised custom-submit-button" ng-click="MakeComments()"> SUBMIT </md-button>
</form>
$scope.uploadFiles = function(file) {
console.log(file);
$scope.fileData = file;
var fd = new FormData();
fd.append('file', file);
Restangular.one('/api/files/end points').withHttpConfig({transformRequest: angular.identity})
.customPOST(fd, '', undefined, {'Content-Type': undefined})
};

How to update data with image using AngularJS $http.put Method

I am created a Laravel application to upload data with image.I am successfully done this task using following way in AngularJs
app.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]);
});
});
}
};
}]);
app.controller('rowController', function($scope,$http,$modal,Row){
$scope.saveItem=function(){
var fd = new FormData();
//fd.append('photo', $scope.myFile);
for(var key in $scope.newrow)
fd.append(key,$scope.newrow[key]);
$http.post('/api/row_material', fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(data,status,headers,config){
console.log(data);
}).error(function(data,status,headers,config){
console.log(data);
});
}
}
Above POST method successfully worked for me.Now I need to update data with image using $http.put() method.I am created a method as listed below;
$scope.updateItem=function(){
var fd = new FormData();
for(var key in $scope.newrow)
fd.append(key,$scope.newrow[key]);
var uri='api/row_material/1';
$http.put(uri,fd,{headers: '{"Content-Type": undefined}'} )
.success(function (data, status, headers, config) {
alert('Updated Successfully.');
})
.error(function (data, status, header, config) {
alert('Server error');
console.log(data);
});
}
But above put method causes an error given below;
<!DOCTYPE html>
<html>
<head>
<meta name="robots" content="noindex,nofollow" />
<style>
/* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}
html { background: #eee[…]
Above put method work with out using FormDate() using following way.But Image not uploaded to server
$scope.updateItem=function(){
var uri='api/row_material/1';
$http.put(uri,$scope.newrow,{headers: '{"Content-Type": undefined}'} )
.success(function (data, status, headers, config) {
alert('Updated Successfully.');
})
.error(function (data, status, header, config) {
alert('Server error');
console.log(data);
});
}
I need your help to update data with image using FormData put method in AngularJS
I would suggest you to use ng file upload plugin. I'm not sure what you are using on the backend but this plugin will help you to send file that is selected from input tag with your data. Check all their demo to get a clear idea.
https://github.com/danialfarid/ng-file-upload
Thanks.
There are several good approaches for this..
One of them is the one given below..
var myApp = angular.module('myApp', []);
myApp.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]);
});
});
}
};
}]);
myApp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
myApp.controller('myCtrl', ['$scope', 'fileUpload', function($scope, fileUpload){
$scope.uploadFile = function(){
var file = $scope.myFile;
console.log('file is ' );
console.dir(file);
var uploadUrl = "/fileUpload";
fileUpload.uploadFileToUrl(file, uploadUrl);
};
}]);
<div ng-app = "myApp" ng-controller = "myCtrl">
<input type = "file" file-model = "myFile"/>
<button ng-click = "uploadFile()">upload me</button>
</div>
This would do for the client side. Now for the server side, you need to write a script that can handle the uploaded image correctly and place it on the destination where you intend to..
This piece from the PHP documentation discusses the PUT method and file uploads (multipart/form-data).
I can't quote any parts from it because I think everything is important. You should read it in detail but to summarize it's not possible without changes to your Apache configuration and creation of auxiliary scripts.
With Laravel you should use [Form Method Spoofing][2] (basically a variable called _method) and keep on using POST. The _method will allow you to call Laravel's PUT action correctly.

Provider 'FileUpload' must return a value from $get factory method

In a web application made with AngularJs there is a page where the user can upload a file. But I have some problem.
This is the Factory that makes the upload:
angular.module('app').factory('FileUpload', ['$http', function($http) {
this.uploadFileToUrl = function(file, uploadUrl){
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
}
}]);
If I try to upload a file, console gives me this error:
"Error: [$injector:undef] Provider 'FileUpload' must return a value from $get factory method.
This is the function in the Controller:
$scope.uploadFile = function(){
var userId = $stateParams.userId;
var fileType = $stateParams.fileType;
var file = $scope.myFile;
console.log('file is ');
console.dir(file);
var uploadUrl = 'my_url';
FileUpload.uploadFileToUrl(file, uploadUrl);
};
The pattern you're using should use service not factory. With factory you want to return the new'd up instance, with service you just provide the function.
angular.module('app').service('FileUpload',...

File upload in Grails application using angular js

I'm working on a Grails (2.3.7) application with AngularJS. I've to upload files in my application. Since the front end is managed by Angular , I'm uploading my file from Angular controller. I've gone through This
and this discussions , and tried to upload as follows.
My file uploader is
<input type="file" ng-file-select="onFileSelect($files)">
Angular controller is
myapp.controller('createWebController',['$scope','$http','$upload',function($scope,$http,$upload){
$scope.onFileSelect = function($files) {
var file = $files[0];
console.log(file)
$upload.upload({
url: 'UploadLogo/upload', //upload.php script, node.js route, or servlet url
file: file,
method: 'POST' ,
fileFormDataName: "myFile",
}).progress(function(evt) {
console.log('percent: ' + parseInt(100.0 * evt.loaded / evt.total));
}).success(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
})
.error(function(data){ console.log(data)})
;
};
}])
on the server , I'm using this service and the upload handler code is
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.MultipartFile
import org.codehaus.groovy.grails.web.context.ServletContextHolder
class UploadLogoController {
FileUploadService fileUploadService
def upload() {
def avatarImage = request.getFile('file')
if (!avatarImage.isEmpty())
{
userInstance.avatar = fileUploadService.uploadFile(avatarImage, "logo.png", "~/Desktop/upload")
render "ok"
}
else
{
render "Empty"
}
}
}
But the problem is I'm getting a 500 (Internal Server Error) from grails. The file is not being uploaded.
also getting response as Cannot invoke method isEmpty() on null object
Which means the file has not been sent to the server. Whats the problem here.. Please help..
Try this way. You could create a custom directive for the file upload control
myapp.directive('ngFileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var model = $parse(attrs.ngFileModel);
var modelSetter = model.assign;
element.bind('change', function(){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
});
}
};}])
and in your html use <input type="file" ng-file-model="myFile" />
Then you could create a custom service to do the file upload. Note that its not necessary to create service but it can easily reuse in later file uploads just by injecting the service.
myapp.service('fileUpload', ['$http', function ($http) {
this.uploadFileToUrl = function(file, uploadUrl,filename){
var fd = new FormData();
fd.append('file', file);
fd.append('filename', filename);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(data){
console.log(data)
})
.error(function(data){ console.log(data)
});
};}]);
The uploadFileToUrl takes 3 arguments , the file itself , the URL to upload and the file name to be saved as.(You can customize this as you wish) . Use the $http.post to post data.
Finally in your controller , include this
var file = $scope.myFile;
var filename = 'YourFileName'
var uploadUrl = '/UploadLogo/upload' // don't forget to include the leading /
fileUpload.uploadFileToUrl(file, uploadUrl,filename);

Resources