Upload file without using Formdata in AngularJs - angularjs

Is there any way to upload files without using formdata in Angular Js. I have checked the below links, which have not helped:
https://stackoverflow.com/questions/32432299/upload-file-using-jquery-without-using-html5
How to send/ Upload file without using FORMDATA in jquery ajax
How can I upload file in JavaScript and PHP without using FormData
I do not want to use any plug-in, and cannot use iframes. I want to upload single file. I have the service created as below, to which I have to pass the image data.
myAPIService.postUploadImage = function (formdata) {
var request = {
url: urlBase + 'UploadImage',
method: 'POST',
data: formdata,
headers: {
'Content-Type': undefined
}
}
return $http(request);
};
The UI is defined as below:
<input type="file" class="form-control" id="imageUploadfile" name="Imagefile" accept="image/*" />
<input type="button" name="imageUploadButton" ng-click="uploadFiles()" value="Upload" />
Requesting Admin/moderators to not mark it as duplicate, as I have tried most of the links, but that has not worked.
How to upload single file in AngularJS without using plugins,iframe and which works in IE 11, Chrome.
Thanks

Related

Upload File and Data with Angularjs in MVC .net core

<input type="file" ng-model="ch.FileName" id="file" name="myFile" nchange="angular.element(this).scope().saveChapter(this.files)"/>
Action Method,Js and other Code
Upload File and Data with Angularjs in MVC .net core
If you'd like to post binary data with other additional information/data from your angularjs frontend to WebAPI backend, you can try to pass the data through FormData object, like below.
var formdata = new FormData();
formdata.append('chapterID', $scope.ch.ChapterID);
formdata.append('bookID', $scope.ch.BookID);
formdata.append('chapterName', $scope.ch.FileName);
//...
formdata.append('cHFile', $scope.chfile);
$http({
method: 'POST',
url: 'your_request_url_here',
headers: { 'Content-Type': undefined },
data: formdata
}).then(function mySuccess(response) {
//...
In browser developer tool Network tab, can find the data passed as expected
Test Result

Uploading file in API makes error 400

I'm working on an API project which communicate with another API, my front is AngularJS
I try to upload a file (a picture) an post it through an API which already works for other posts (other posts are not uploads, just data)
I can upload the picture and treat it in a formdata, but when I try to post it, I have a 400 error with no 'Access-Control-Allow-Origin'. But my others post methods work well but this one makes trouble.
My Ajax post method:
apiDataService.postPicture = function(formData, callback) {
$http({
method: 'POST',
url: apiUrl + '/pictures',
data: formData,
contentType: false,
processData: false,
headers: {
'Authorization': localStorageService.get('auth')
}
}).then(function successCallback(response) {
// retrieve response data
callback(response.data);
}, function errorCallback(response) {
// an error occured
});
};
I took the pattern of my others post methods so, it would works...
My uploading function:
self.addPicture = (image) => {
var fileInput = document.getElementById('the-file');
var file = fileInput.files[0];
var formData = new FormData();
formData.append('file', file);
apiDataService.postPicture(formData);
}
And my view:
<form id="form-id">
<div class="col-xs-12">
<span>Image :</span>
<br/>
<input id="the-file" type="file" placeholder="Image du Procédé" ng-model="picture.file" class="form-control" />
</div>
<div class="col-xs-12">
<button ng-click="addPicture(image)">Enregistrer image</button>
</div>
</form>
If you have any ideas, I don't understand my error...
It is certainly due to your CORS options your server are using. Maybe you don't allow data header or something like that.
#Nounnoune can you try to add below header I had Same Problem so I added below header and work like charm .
'Content-type': 'application/x-www-form-urlencoded; charset=utf-8'
There are already many Angular.js modules to perform file uploading.
These two have explicit support for older browsers:
Uses iframes as a fallback
Uses FileAPI/Flash as a fallback
I finally got a good form, a basic one only in HTML, it's not as pretty as I would like it to be, but it works! Just have to optimize it.

Using Fetch API with cross-fetch polyfill to upload file on file-input change

I'm using the Fetch API with the cross-fetch polyfill https://www.npmjs.com/package/cross-fetch
Been farting around on SO for several hours trying to get file upload working using it. No matter what I do, I can't seem to avoid the 'unsupported BodyInit type' error.
<input
name="file"
type="file"
onChange={event => {
event.preventDefault();
var f = event.target.files[0];
var data = new FormData();
data.append("file", f);
fetch("/my-api", {
method: "POST",
body: data
});
}}
/>
Here's a runnable example: https://codesandbox.io/s/v08lpj24wy
Of course, I wouldn't do this sort of thing inside an onChange handler directly, but the example illustrates the error. What am I doing wrong?
Turns out your import fetch from "cross-fetch" is shimming fetch incorrectly, by breaking the parsing of blobs and FormData. Just remove the import and see that everything works.
fetch returns a promise. It doesn't do anything until you call then
edit
If you call fetch with a Request object the error dissapears
var req = new Request("/my-api", {
method: "POST",
body: data
});
fetch(req)
.then(() => console.log("ok"))
.catch(() => console.error("not ok"));
Actually that's an issue with github's fetch that cross-fetch uses to fetch on the browser environment. http://github.com/github/fetch/issues/601
You can't pass a file directly as body. You must take the 2nd approach
by wrapping it in a FormData. When passing a FormData to body, you
must not set any Content-Type header for the request. Instead, the
browser will choose the appropriate multipart/form-data value.

How to send file to Sails from AngularJS without using custom directives?

So I need to upload an image to the server. Right now it works only with a POST request made via HTML. But I need to send other data and do other stuff before uploading it, so I'd like to send the request inside an Angular controller, using $http.post(...). I've seen some really complex solutions using custom directives, but I'd like to know if there's anyway to do something straight forward like:
$scope.uploadPhoto = function(){
var fd = new FormData();
fd.append("uploadFile", $scope.file);
$http.post('file/upload', fd);
}
Working code:
HTML:
<form id="uploadForm"
enctype="multipart/form-data"
action="/file/upload"
method="post">
<input type="file" name="uploadFile" />
<input type="submit" value="submit"/>
</form>
Sails Controller:
upload: function (req, res) {
var uploadFile = req.file('uploadFile');
uploadFile.upload(
{ dirname: '../../assets/images',
saveAs: function(file, cb) {
cb(null, file.filename);
}
}, function onUploadComplete (err, files) {
if (err) return res.serverError(err);
res.json({status:200,file:files});
});
}

AngularJS: how to implement a simple file upload with multipart form?

I want to do a simple multipart form post from AngularJS to a node.js server,
the form should contain a JSON object in one part and an image in the other part,
(I'm currently posting only the JSON object with $resource)
I figured I should start with input type="file", but then found out that AngularJS can't bind to that..
all the examples I can find are for wraping jQuery plugins for drag & drop. I want a simple upload of one file.
I'm new to AngularJS and don't feel comfortable at all with writing my own directives.
A real working solution with no other dependencies than angularjs (tested with v.1.0.6)
html
<input type="file" name="file" onchange="angular.element(this).scope().uploadFile(this.files)"/>
Angularjs (1.0.6) not support ng-model on "input-file" tags so you have to do it in a "native-way" that pass the all (eventually) selected files from the user.
controller
$scope.uploadFile = function(files) {
var fd = new FormData();
//Take the first selected file
fd.append("file", files[0]);
$http.post(uploadUrl, fd, {
withCredentials: true,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).success( ...all right!... ).error( ..damn!... );
};
The cool part is the undefined content-type and the transformRequest: angular.identity that give at the $http the ability to choose the right "content-type" and manage the boundary needed when handling multipart data.
You can use the simple/lightweight ng-file-upload directive.
It supports drag&drop, file progress and file upload for non-HTML5 browsers with FileAPI flash shim
<div ng-controller="MyCtrl">
<input type="file" ngf-select="onFileSelect($files)" multiple>
</div>
JS:
//inject angular file upload directive.
angular.module('myApp', ['ngFileUpload']);
var MyCtrl = [ '$scope', 'Upload', function($scope, Upload) {
$scope.onFileSelect = function($files) {
Upload.upload({
url: 'my/upload/url',
file: $files,
}).progress(function(e) {
}).then(function(data, status, headers, config) {
// file is uploaded successfully
console.log(data);
});
}];
It is more efficient to send a file directly.
The base64 encoding of Content-Type: multipart/form-data adds an extra 33% overhead. If the server supports it, it is more efficient to send the files directly:
$scope.upload = function(url, file) {
var config = { headers: { 'Content-Type': undefined },
transformResponse: angular.identity
};
return $http.post(url, file, config);
};
When sending a POST with a File object, it is important to set 'Content-Type': undefined. The XHR send method will then detect the File object and automatically set the content type.
To send multiple files, see Doing Multiple $http.post Requests Directly from a FileList
I figured I should start with input type="file", but then found out that AngularJS can't bind to that..
The <input type=file> element does not by default work with the ng-model directive. It needs a custom directive:
Working Demo of "select-ng-files" Directive that Works with ng-model1
angular.module("app",[]);
angular.module("app").directive("selectNgFiles", function() {
return {
require: "ngModel",
link: function postLink(scope,elem,attrs,ngModel) {
elem.on("change", function(e) {
var files = elem[0].files;
ngModel.$setViewValue(files);
})
}
}
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app">
<h1>AngularJS Input `type=file` Demo</h1>
<input type="file" select-ng-files ng-model="fileArray" multiple>
<h2>Files</h2>
<div ng-repeat="file in fileArray">
{{file.name}}
</div>
</body>
$http.post with content type multipart/form-data
If one must send multipart/form-data:
<form role="form" enctype="multipart/form-data" name="myForm">
<input type="text" ng-model="fdata.UserName">
<input type="text" ng-model="fdata.FirstName">
<input type="file" select-ng-files ng-model="filesArray" multiple>
<button type="submit" ng-click="upload()">save</button>
</form>
$scope.upload = function() {
var fd = new FormData();
fd.append("data", angular.toJson($scope.fdata));
for (i=0; i<$scope.filesArray.length; i++) {
fd.append("file"+i, $scope.filesArray[i]);
};
var config = { headers: {'Content-Type': undefined},
transformRequest: angular.identity
}
return $http.post(url, fd, config);
};
When sending a POST with the FormData API, it is important to set 'Content-Type': undefined. The XHR send method will then detect the FormData object and automatically set the content type header to multipart/form-data with the proper boundary.
I just had this issue. So there are a few approaches. The first is that new browsers support the
var formData = new FormData();
Follow this link to a blog with info about how support is limited to modern browsers but otherwise it totally solves this issue.
Otherwise you can post the form to an iframe using the target attribute.
When you post the form be sure to set the target to an iframe with its display property set to none.
The target is the name of the iframe. (Just so you know.)
I hope this helps
You could upload via $resource by assigning data to params attribute of resource actions like so:
$scope.uploadFile = function(files) {
var fdata = new FormData();
fdata.append("file", files[0]);
$resource('api/post/:id', { id: "#id" }, {
postWithFile: {
method: "POST",
data: fdata,
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
}
}).postWithFile(fdata).$promise.then(function(response){
//successful
},function(error){
//error
});
};
I know this is a late entry but I have created a simple upload directive. Which you can get working in no time!
<input type="file" multiple ng-simple-upload web-api-url="/api/post"
callback-fn="myCallback" />
ng-simple-upload more on Github with an example using Web API.
I just wrote a simple directive (from existing one ofcourse) for a simple uploader in AngularJs.
(The exact jQuery uploader plugin is https://github.com/blueimp/jQuery-File-Upload)
A Simple Uploader using AngularJs (with CORS Implementation)
(Though the server side is for PHP, you can simple change it node also)

Resources