In this tutorial, we will learn How to Upload files like Excel, Image or any document like PDFs to a Web Server in Angular application using FormGroup class and FormData interface.
This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11, Angular 12 and Angular 13
We are going to create a simple form that will have a file input control to select a file which will be uploaded by clicking on a button.
In Angular, we use the FormData
to handle forms that represent the form field controls as we have in a static HTML page.
How to Upload Files in Angular using FormData?
Step 1) Import required modules
To enable a form to upload files to a remote server using the HTTP post method in Angular application, we need to import FormsModule
, ReactiveFormsModule
and HttpClientModule
in the app.module.ts file as shown below:
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Step 2) Adding a Form in Component Template
Add a simple Form in a component template HTML with [formGroup]
and (ngSubmit)
event handler. Then add an Input File control and a button to submit the form as shown below:
<h3>Upload File</h3>
<form [formGroup]="fileUploadForm" (ngSubmit)="onFormSubmit()">
<div class="row">
<div class="col-sm-12">
<div>
<h6 class="head-title margin-top-8"><span>UPLOAD</span></h6>
</div>
</div>
<div class="col-sm-6 text-center">
<div class="custom-file">
<input type="file" class="custom-file-input" id="customFile" name="myfile"
(change)="onFileSelect($event)" #UploadFileInput>
<label class="custom-file-label" for="customFile">{{fileInputLabel || 'Choose File'}}</label>
</div>
</div>
<div class="col-sm-6 text-center">
<button class="btn btn-primary" type="submit">Upload</button>
</div>
</div>
</form>
Above we also added a template reference variable #UploadFileInput
to reset the input field after file uploaded successfully.
Note: To this form look good, we used bootstrap.css in the index.html file
Step 3) Update Component class file
Next, we will add a reference to the input file control using @ViewChild
as ElementRef
.
onFileSelect()
method is called when a file is selected. It is also having a check for Excel file, but you can add your own file type checks for Docs, PDFs or Images or simply remove this check for all file types.onFormSubmit()
method is called on form submit, here you can add more formData properties if you want using FormData's append
methodimport { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
import * as _ from 'lodash';
@Component({
selector: 'app-uploadfile',
templateUrl: './uploadfile.component.html',
styleUrls: ['./uploadfile.component.scss']
})
export class UploadfileComponent implements OnInit {
@ViewChild('UploadFileInput', { static: false }) uploadFileInput: ElementRef;
fileUploadForm: FormGroup;
fileInputLabel: string;
constructor(
private http: HttpClient,
private formBuilder: FormBuilder
) { }
ngOnInit(): void {
this.fileUploadForm = this.formBuilder.group({
myfile: ['']
});
}
onFileSelect(event) {
let af = ['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel']
if (event.target.files.length > 0) {
const file = event.target.files[0];
// console.log(file);
if (!_.includes(af, file.type)) {
alert('Only EXCEL Docs Allowed!');
} else {
this.fileInputLabel = file.name;
this.fileUploadForm.get('myfile').setValue(file);
}
}
}
onFormSubmit() {
if (!this.fileUploadForm.get('myfile').value) {
alert('Please fill valid details!');
return false;
}
const formData = new FormData();
formData.append('formFile', this.fileUploadForm.get('myfile').value);
formData.append('agentId', '007');
this.http
.post<any>('http://www.example.com/api/upload', formData).subscribe(response => {
console.log(response);
if (response.statusCode === 200) {
// Reset the file input
this.uploadFileInput.nativeElement.value = "";
this.fileInputLabel = undefined;
}
}, error => {
console.log(error);
});
}
}
Note: In the onFileSelect method we used _.includes
lodash method to find a match in the array. The lodash is added by default in the latest Angular versions.