Actually, I'm working on a Spring REST API with an interface coded in Angular 2.
My problem is I can't upload a file with Angular 2.
My Webresources in java is that :
@RequestMapping(method = RequestMethod.POST, value = "/upload")
public String handleFileUpload(@RequestParam MultipartFile file) {
//Dosomething
}
And it is perfectly working when I call it through URL request with Auth header etc ... ( with Advanced Rest Client extension for Chrome )
Proof: (everything works fine in that case )
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
Spring config file and the Pom dependency
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2</version>
</dependency>
BUT when I try to do the same thing with a webform :
<input type="file" #files (change)="change(files)"/>
<pre>{{fileContents$|async}}</pre>
With the (change) method :
change(file) {
let formData = new FormData();
formData.append("file", file);
console.log(formData);
let headers = new Headers({
'Authorization': 'Bearer ' + this.token,
'Content-Type': 'multipart/form-data'
});
this.http.post(this.url, formData, {headers}).map(res => res.json()).subscribe((data) => console.log(data));
/*
Observable.fromPromise(fetch(this.url,
{method: 'post', body: formData},
{headers: this.headers}
)).subscribe(()=>console.log('done'));
*/
}
My web service returns me an error 500, with that in tomcat logs: http://pastebin.com/PGdcFUQb
I tried the 'Content-Type': undefined
method too but without success ( the web service return me a 415 error in that case.
Can someone help me to figure out what's the problem is?
Problem solved, I'll update that question later with my code :) but, have a look on the plunker it's working perfectly well. Thanks.
This is actually really easy to do in the final release. Took me a while to wrap my head around it because most information about it that I've come across is outdated. Posting my solution here in case anyone else is struggling with this.
import { Component, ElementRef, Input, ViewChild } from '@angular/core';
import { Http } from '@angular/http';
@Component({
selector: 'file-upload',
template: '<input type="file" [multiple]="multiple" #fileInput>'
})
export class FileUploadComponent {
@Input() multiple: boolean = false;
@ViewChild('fileInput') inputEl: ElementRef;
constructor(private http: Http) {}
upload() {
let inputEl: HTMLInputElement = this.inputEl.nativeElement;
let fileCount: number = inputEl.files.length;
let formData = new FormData();
if (fileCount > 0) { // a file was selected
for (let i = 0; i < fileCount; i++) {
formData.append('file[]', inputEl.files.item(i));
}
this.http
.post('http://your.upload.url', formData)
// do whatever you do...
// subscribe to observable to listen for response
}
}
}
Then just use it like so:
<file-upload #fu (change)="fu.upload()" [multiple]="true"></file-upload>
That is really all there is to it.
Alternatively, capture the event object and get the files from the srcElement. Not sure if any way is better than the other, to be honest!
Keep in mind FormData is IE10+, so if you have to support IE9 you'll need a polyfill.
Update 2017-01-07
Updated code to be able to handle uploading of multiple files. Also my original answer was missing a rather crucial bit concerning FormData (since I moved the actual upload logic to a separate service in my own app I was handling it there).
Sure! But this question is the first one that comes up on Google when you search for "angular 2 file upload". Figured I'd add some up to date information.
What version of RC are you on? Has anyone else had success using this? Doesn't seem to be working for me.
Okay I am a little bit confused, the fileupload seems to be working but the weird thing is, that since im running with localhost:3000 the upload cant find the uploadfolder (maybe because of the routes?) and when I just link localhost/folder I get a cors error any ideas on this?
If anyone else was wondering where FormData came from, its the native FormData object: developer.mozilla.org/en-US/docs/Web/API/FormData/FormData You dont need to import anything.
This works great! One caveat - make sure not to manually set the Content-Type header. Leaving it unspecified, Angular 2 seems to choose the right value, at least between application/json and multipart/form-data