The following code attempts to send a file from an Angular2 app. It always end-up in the REST API not being able to recognize the file in the request it is receiving. (Even if the content seams to be there !)
After spending hours searching StackOverflow and countless other online sources, i came to the conclusion that the most recent version of Angular2 Http module/service should now be capable of handling file uploads. (The fact that it wasn't able to do so in the past is just amazing !) See this article or even this git sample.
If i am to use an external lib like ng2-file-upload, it needs to be able to replace Angular2::Http with as little modification as possible to the following code. (i.e. I cannot change the HTML form.)
Component.html
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()" novalidate>
<label>Votre avatar !</label>
<input class="form-control" type="file" name="avatar" (change)="imageUpload($event)" >
Component.ts
imageUpload(e) {
let reader = new FileReader();
//get the selected file from event
let file = e.target.files[0];
reader.onloadend = () => {
this.image = reader.result;
}
reader.readAsDataURL(file);
}
onSubmit() {
if (this.image){
this.authService.setAvatar(this.image).subscribe(
d => {
//Do Nothing... Will navigate to this.router.url anyway so...
},
err =>{
this.errorMessage = err;
console.log(err);
}
);
}
}
authService.ts
setAvatar(image:any){
let form: FormData = new FormData();
form.append('avatar', image);
return this.http.post (Config.REST_URL + 'user/setAvatar?token=' +localStorage.getItem('token'), form,
{headers: new Headers({'X-Requested-With': 'XMLHttpRequest' })}
).catch(this.handleError);
}
REST_API Php (LARAVEL)
public function setAvatar(Request $request){
if($request->hasFile("avatar")) { // ALWAYS FALSE !!!!
$avatar = $request->file("avatar");
$filename = time() . "." . $avatar->getClientOriginalExtension();
Image::make($avatar)->fit(300)->save(public_path("/uploads/avatars/" . $filename));
return response()->json(['message' => "Avatar added !"], 200);
}
return response()->json(['message' => "Error_setAvatar: No file provided !"], 200);
}
Content of the Request Payload (As seen from Chrome Inspect/Network)
------WebKitFormBoundary8BxyBbDYFTYpOyDP
Content-Disposition: form-data; name="avatar"
Should be more like...:
Content-Disposition: form-data; name="avatar"; filename="vlc926.png"
Content-Type: image/png
Turns out Angular2's Http can now send files... And it's super easy !.... I just can't believe there are just no documentation out there showing this ! Except this one. (Credits to MICHAŁ DYMEL)
The HTML
<input #fileInput type="file"/>
<button (click)="addFile()">Add</button>
Component.ts
@ViewChild("fileInput") fileInput;
addFile(): void {
let fi = this.fileInput.nativeElement;
if (fi.files && fi.files[0]) {
let fileToUpload = fi.files[0];
this.uploadService
.upload(fileToUpload)
.subscribe(res => {
console.log(res);
});
}
}
The service.ts
upload(fileToUpload: any) {
let input = new FormData();
input.append("file", fileToUpload);
return this.http.post("/api/uploadFile", input);
}