How do I load a multi-page form in AngularJS?
Form type:
<form enctype="multipart/form-data" ng-submit="upload(file)">
<input type="file" ng-model="modal.file" accept="image/gif" app-filereader /><br />
<br>
<textarea name="description" placeholder="Description" ng-model="description" id="" cols="30" rows="10"></textarea>
<br>
<input type="hidden" name="user" ng-model="user" value="{{ user }}" />
<br>
<input type="submit" value="Submit" class="network-sensitive button button-block button" />
</form>
Directive
.directive('appFilereader', function(
$q
){
var slice = Array.prototype.slice;
return {
restrict: 'A'
, require: '?ngModel'
, link: function(scope, element, attrs, ngModel){
if(!ngModel) return;
ngModel.$render = function(){}
element.bind('change', function(e){
var element = e.target;
$q.all(slice.call(element.files, 0).map(readFile))
.then(function(values){
if(element.multiple) ngModel.$setViewValue(values);
else ngModel.$setViewValue(values.length ? values[0] : null);
});
function readFile(file) {
var deferred = $q.defer();
var reader = new FileReader()
reader.onload = function(e){
deferred.resolve(e.target.result);
}
reader.onerror = function(e) {
deferred.reject(e);
}
reader.readAsDataURL(file);
return deferred.promise;
}
});
}
};
});
Download function in my services:
upload: function(file) {
var token = $window.sessionStorage.token;
var url = 'http://url.co/api/posts/creates';
var $cache = $cacheFactory.get('$http');
var deffered = $q.defer();
var data = $cache.get(url);
if(!data) {
$http({
url: url,
method: "POST",
params: { access_token: token },
data: file,
headers: {'Content-Type': undefined },
transformRequest: angular.identity
}).then(function(res) {
deffered.resolve(res);
});
} else {
deffered.resolve(data);
}
return deffered.promise;
}
I didn't include the controller code as it was just passing the form data from the modal service and the part that works.
The problem I am facing is that the file is being transferred as encoded data (my knowledge is a little shaky about binary data and blocks, etc.). And my API (written in Symfony2) expects a normal file feed as opposed to a data string.
So how would I convert this binary block into an image file that I can send? Or am I missing something?
source to share
use this module https://github.com/danialfarid/angular-file-upload very easy to use.
ex:
var $file;//single file
$scope.sendFiles= function(){
$upload.upload({
url: yourUrl,
method: "POST",
data: { data: $scope.yourOtherObject },
file: $file
}).success(function (data, status, headers, config) {
// file is uploaded successfully
console.log(data);
console.log("File upload SUCCESS");
}).error(function (data, status) {
console.log("File upload FAILED");
});
}
$scope.onFileSelect = function ($files) {
for (var i = 0; i < $files.length; i++) {
$file = $files[i];//set a single file
}
};
HTML CODE
<input type="file" name="myfile" ng-file-select="onFileSelect($files)" />
<button ng-click='sendFiles()'>Send file</button>
source to share
The problem is with the $ http service, the default content type is application / json and in your case it should be application / x-www-form-urlencoded To solve this problem you can use the following directive: https: // github. com / nervgh / angular-file-upload / wiki / Module-API , it also supports uploading data along with files.
Another approach is to use the formData object along with the XmlHttpRequest in your directive, for example:
var data = new FormData();
var xhr = new XMLHttpRequest();
data.append('file', files[i], files[i].name);
xhr.open('POST', scope.mseUploadFile);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var result = xhr.responseText;
if (scope.callback) {
scope.$apply(function () {
scope.callback({ $data: result });
});
}
}
else if (xhr.readyState == 4 && xhr.status == 400) {
scope.$apply(function () {
if (scope.onError) {
scope.onError({ $error: xhr.responseText });
}
handleError(xhr.responseText);
});
}
};
xhr.send(data);
source to share