Uploading a file in Angular?

I know this is a very general question, but I cannot upload the file in Angular 2. I tried

1) http://valor-software.com/ng2-file-upload/ and

2) http://ng2-uploader.com/home

... but failed. Has anyone uploaded a file in Angular? What method did you use? How to do it? If any sample code or a demo link is provided, this will really be appreciated.

+149
angular file-upload
Oct 24 '16 at 9:18
source share
13 answers

Angular 2 provides good support for downloading files. No third-party library is required.

<input type="file" (change)="fileChange($event)" placeholder="Upload file" accept=".pdf,.doc,.docx"> fileChange(event) { let fileList: FileList = event.target.files; if(fileList.length > 0) { let file: File = fileList[0]; let formData:FormData = new FormData(); formData.append('uploadFile', file, file.name); let headers = new Headers(); /** In Angular 5, including the header Content-Type can invalidate your request */ headers.append('Content-Type', 'multipart/form-data'); headers.append('Accept', 'application/json'); let options = new RequestOptions({ headers: headers }); this.http.post('${this.apiEndPoint}', formData, options) .map(res => res.json()) .catch(error => Observable.throw(error)) .subscribe( data => console.log('success'), error => console.log(error) ) } } 

using @ angular / core ":" ~ 2.0.0 "and @ angular / http:" ~ 2.0.0 "

+338
Oct 24 '16 at 10:52
source share

From the answers above I will build this with Angular 5.x

Just call uploadFile(url, file).subscribe() to force the download

 import { Injectable } from '@angular/core'; import {HttpClient, HttpParams, HttpRequest, HttpEvent} from '@angular/common/http'; import {Observable} from "rxjs"; @Injectable() export class UploadService { constructor(private http: HttpClient) { } // file from event.target.files[0] uploadFile(url: string, file: File): Observable<HttpEvent<any>> { let formData = new FormData(); formData.append('upload', file); let params = new HttpParams(); const options = { params: params, reportProgress: true, }; const req = new HttpRequest('POST', url, formData, options); return this.http.request(req); } } 

Use it in your component

  // At the drag drop area // (drop)="onDropFile($event)" onDropFile(event: DragEvent) { event.preventDefault(); this.uploadFile(event.dataTransfer.files); } // At the drag drop area // (dragover)="onDragOverFile($event)" onDragOverFile(event) { event.stopPropagation(); event.preventDefault(); } // At the file input element // (change)="selectFile($event)" selectFile(event) { this.uploadFile(event.target.files); } uploadFile(files: FileList) { if (files.length == 0) { console.log("No file selected!"); return } let file: File = files[0]; this.upload.uploadFile(this.appCfg.baseUrl + "/api/flash/upload", file) .subscribe( event => { if (event.type == HttpEventType.UploadProgress) { const percentDone = Math.round(100 * event.loaded / event.total); console.log('File is ${percentDone}% loaded.'); } else if (event instanceof HttpResponse) { console.log('File is completely loaded!'); } }, (err) => { console.log("Upload Error:", err); }, () => { console.log("Upload done"); } ) } 
+60
Dec 01 '17 at 16:25
source share

Thanks @Eswar. This code worked fine for me. I want to add certain things to the solution:

I was getting the error: java.io.IOException: RESTEASY007550: Unable to get boundary for multipart

To resolve this error, you must remove the "Content-Type" "multipart / form-data". He solved my problem.

+22
Oct 25 '16 at 8:34
source share

Since the sample code is a bit dated, it seemed to me that I would use a more recent approach using Angular 4.3 and the new (er) HttpClient API, @ angular / common / http

 export class FileUpload { @ViewChild('selectedFile') selectedFileEl; uploadFile() { let params = new HttpParams(); let formData = new FormData(); formData.append('upload', this.selectedFileEl.nativeElement.files[0]) const options = { headers: new HttpHeaders().set('Authorization', this.loopBackAuth.accessTokenId), params: params, reportProgress: true, withCredentials: true, } this.http.post('http://localhost:3000/api/FileUploads/fileupload', formData, options) .subscribe( data => { console.log("Subscribe data", data); }, (err: HttpErrorResponse) => { console.log(err.message, JSON.parse(err.error).error.message); } ) .add(() => this.uploadBtn.nativeElement.disabled = false);//teardown } 
+18
Oct 26 '17 at 13:07 on
source share

In Angular 2+, it's important leave Content-Type empty. If you set "Content-Type" to "multipart / form-data", the download will not work!

upload.component.html

 <input type="file" (change)="fileChange($event)" name="file" /> 

upload.component.ts

 export class UploadComponent implements OnInit { constructor(public http: Http) {} fileChange(event): void { const fileList: FileList = event.target.files; if (fileList.length > 0) { const file = fileList[0]; const formData = new FormData(); formData.append('file', file, file.name); const headers = new Headers(); // It is very important to leave the Content-Type empty // do not use headers.append('Content-Type', 'multipart/form-data'); headers.append('Authorization', 'Bearer ' + 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9....'); const options = new RequestOptions({headers: headers}); this.http.post('https://api.mysite.com/uploadfile', formData, options) .map(res => res.json()) .catch(error => Observable.throw(error)) .subscribe( data => console.log('success'), error => console.log(error) ); } } } 
+15
Oct 26 '17 at 15:05
source share

I used the following priming tool with success. I have no skin in the game with PrimeNg, just conveying my offer.

http://www.primefaces.org/primeng/#/fileupload

+8
Oct 24 '16 at 10:49
source share

This simple solution worked for me: file-upload.component.html

 <div> <input type="file" #fileInput placeholder="Upload file..." /> <button type="button" (click)="upload()">Upload</button> </div> 

And then load the component directly using XMLHttpRequest.

 import { Component, OnInit, ViewChild } from '@angular/core'; @Component({ selector: 'app-file-upload', templateUrl: './file-upload.component.html', styleUrls: ['./file-upload.component.css'] }) export class FileUploadComponent implements OnInit { @ViewChild('fileInput') fileInput; constructor() { } ngOnInit() { } private upload() { const fileBrowser = this.fileInput.nativeElement; if (fileBrowser.files && fileBrowser.files[0]) { const formData = new FormData(); formData.append('files', fileBrowser.files[0]); const xhr = new XMLHttpRequest(); xhr.open('POST', '/api/Data/UploadFiles', true); xhr.onload = function () { if (this['status'] === 200) { const responseText = this['responseText']; const files = JSON.parse(responseText); //todo: emit event } else { //todo: error handling } }; xhr.send(formData); } } } 

If you use the dotnet kernel, the parameter name must match the field name. files in this case:

 [HttpPost("[action]")] public async Task<IList<FileDto>> UploadFiles(List<IFormFile> files) { return await _binaryService.UploadFilesAsync(files); } 

This answer is plagiarized http://blog.teamtreehouse.com/uploading-files-ajax

Edit : After downloading, you need to clear the file download so that the user can select a new file. And instead of using XMLHttpRequest, it might be better to use fetch:

 private addFileInput() { const fileInputParentNative = this.fileInputParent.nativeElement; const oldFileInput = fileInputParentNative.querySelector('input'); const newFileInput = document.createElement('input'); newFileInput.type = 'file'; newFileInput.multiple = true; newFileInput.name = 'fileInput'; const uploadfiles = this.uploadFiles.bind(this); newFileInput.onchange = uploadfiles; oldFileInput.parentNode.replaceChild(newFileInput, oldFileInput); } private uploadFiles() { this.onUploadStarted.emit(); const fileInputParentNative = this.fileInputParent.nativeElement; const fileInput = fileInputParentNative.querySelector('input'); if (fileInput.files && fileInput.files.length > 0) { const formData = new FormData(); for (let i = 0; i < fileInput.files.length; i++) { formData.append('files', fileInput.files[i]); } const onUploaded = this.onUploaded; const onError = this.onError; const addFileInput = this.addFileInput.bind(this); fetch('/api/Data/UploadFiles', { credentials: 'include', method: 'POST', body: formData, }).then((response: any) => { if (response.status !== 200) { const error = `An error occured. Status: ${response.status}`; throw new Error(error); } return response.json(); }).then(files => { onUploaded.emit(files); addFileInput(); }).catch((error) => { onError.emit(error); }); } 

https://github.com/yonexbat/cran/blob/master/cranangularclient/src/app/file-upload/file-upload.component.ts

+6
Sep 21 '17 at 19:03
source share

This is a useful guide on how to upload a file using ng2 file download and WITHOUT ng2 download file.

It helps me a lot.

The manual currently contains a couple of errors:

1- The client must have the same download URL as a server, so change in the line app.component.ts

const URL = 'http://localhost:8000/api/upload';

to

const URL = 'http://localhost:3000';

2- The response to sending the server as "text / html", so in app.component.ts change

 .post(URL, formData).map((res:Response) => res.json()).subscribe( //map the success function and alert the response (success) => { alert(success._body); }, (error) => alert(error)) 

to

 .post(URL, formData) .subscribe((success) => alert('success'), (error) => alert(error)); 
+3
Jun 30 '17 at 16:03
source share

To upload an image with form fields

 SaveFileWithData(article: ArticleModel,picture:File): Observable<ArticleModel> { let headers = new Headers(); // headers.append('Content-Type', 'multipart/form-data'); // headers.append('Accept', 'application/json'); let requestoptions = new RequestOptions({ method: RequestMethod.Post, headers:headers }); let formData: FormData = new FormData(); if (picture != null || picture != undefined) { formData.append('files', picture, picture.name); } formData.append("article",JSON.stringify(article)); return this.http.post("url",formData,requestoptions) .map((response: Response) => response.json() as ArticleModel); } 

In my case, I needed .NET Web Api in C #

 // POST: api/Articles [ResponseType(typeof(Article))] public async Task<IHttpActionResult> PostArticle() { Article article = null; try { HttpPostedFile postedFile = null; var httpRequest = HttpContext.Current.Request; if (httpRequest.Files.Count == 1) { postedFile = httpRequest.Files[0]; var filePath = HttpContext.Current.Server.MapPath("~/" + postedFile.FileName); postedFile.SaveAs(filePath); } var json = httpRequest.Form["article"]; article = JsonConvert.DeserializeObject <Article>(json); if (!ModelState.IsValid) { return BadRequest(ModelState); } article.CreatedDate = DateTime.Now; article.CreatedBy = "Abbas"; db.articles.Add(article); await db.SaveChangesAsync(); } catch (Exception ex) { int a = 0; } return CreatedAtRoute("DefaultApi", new { id = article.Id }, article); } 
+3
Dec 13 '17 at 23:06
source share

Today I integrated the ng2-file-upload package into my application with angular 6, it was pretty simple, please find the high level code below.

import ng2 file upload module

app.module.ts

  import { FileUploadModule } from 'ng2-file-upload'; ------ ------ imports: [ FileUploadModule ], ------ ------ 

Component ts file import FileUploader

app.component.ts

  import { FileUploader, FileLikeObject } from 'ng2-file-upload'; ------ ------ const URL = 'http://localhost:3000/fileupload/'; ------ ------ public uploader: FileUploader = new FileUploader({ url: URL, disableMultipart : false, autoUpload: true, method: 'post', itemAlias: 'attachment' }); public onFileSelected(event: EventEmitter<File[]>) { const file: File = event[0]; console.log(file); } ------ ------ 

HTML component add file tag

app.component.html

  <input type="file" #fileInput ng2FileSelect [uploader]="uploader" (onFileSelected)="onFileSelected($event)" /> 

Work network stackblitz Link: https://ng2-file-upload-example.stackblitz.io

Stackblitz code example: https://stackblitz.com/edit/ng2-file-upload-example

Official documentation https://valor-software.com/ng2-file-upload/

+1
Sep 24 '18 at 7:25
source share

I upload the file using the link. A package is not required to download a file in this way.

// code to be written to the .ts file

 @ViewChild("fileInput") fileInput; addFile(): void { let fi = this.fileInput.nativeElement; if (fi.files && fi.files[0]) { let fileToUpload = fi.files[0]; this.admin.addQuestionApi(fileToUpload) .subscribe( success => { this.loading = false; this.flashMessagesService.show('Uploaded successfully', { classes: ['alert', 'alert-success'], timeout: 1000, }); }, error => { this.loading = false; if(error.statusCode==401) this.router.navigate(['']); else this.flashMessagesService.show(error.message, { classes: ['alert', 'alert-danger'], timeout: 1000, }); }); } 

}

// code to be written in the service.ts file

 addQuestionApi(fileToUpload: any){ var headers = this.getHeadersForMultipart(); let input = new FormData(); input.append("file", fileToUpload); return this.http.post(this.baseUrl+'addQuestions', input, {headers:headers}) .map(response => response.json()) .catch(this.errorHandler); 

}

// code to be written in html

 <input type="file" #fileInput> 
0
Nov 23 '17 at 5:23
source share

Try not setting options options

this.http.post(${this.apiEndPoint}, formData)

and make sure you do not install globalHeaders in your Http factory.

0
Jun 28 '18 at 13:32
source share

In its simplest form, the following code works in Angular 6/7

 this.http.post("http://destinationurl.com/endpoint", fileFormData) .subscribe(response => { //handle response }, err => { //handle error }); 

Here is the full implementation

0
May 4 '19 at 9:20
source share



All Articles