How to Implement File Upload in Angular
In this article, see how to implement file upload in Angular.
Join the DZone community and get the full member experience.
Join For FreeUploading files is an integral part of most projects. However, when considering a file upload method, you should carefully assess the needs of your project. You can manually upload files using Angular components, like FormData, HttpClientModule, and reactive forms. Each of these components will serve different purposes.
In this article, you will learn about popular Angular components for file upload, including a quick tutorial on how to implement file upload in Angular 9.
What Is Angular?
Angular is a development platform and framework that you can use to create single-page applications in JavaScript (JS) or TypeScript (TS). The framework is written in TS and is implemented through libraries that you can import into your projects.
The basic structure of Angular is based on NgModules, collections of components organized into functional sets. These modules enable you to define your Angular applications and integrate various components. Each application you create in Angular has a root module, which enables bootstrapping, and however many feature modules you need.
Within each module are components. These components define the views that are available for use in your application. Views are sets of screen elements that you can apply code to. Additionally, components include services. Services are classes that provide functionality and enable you to create efficient modular applications.
When you use components and the services inside, you are reliant on metadata to define types and usage. The metadata is what associates components with view templates, combining HTML with Angular directives and markup. This then enables you to modify HTML before rendering. Metadata is also how Angular makes services available via dependency injection.
Angular Components for File Upload
Within Angular, there are several components that you can use to achieve file uploads manually. Depending on how you want to use uploads, you may need to modify your use of these methods or you may be able to simply adopt pre-built file upload methods. For example, if you are using a digital asset management tool, many solutions provide methods you can add easily.
Below are the elements commonly used to accomplish file uploads with Angular.
FormData
FormData is an object you can use to store key-value pairs. It enables you to build an object that aligns with an HTML form. This functionality allows you to send data, such as file uploads, to REST API endpoints via HTTP client libraries or the XMLHttpRequest interface.
To create a FormData object you can use the following:
const formData = new FormData();
This method enables you to directly add key-values or to collect data from your existing HTML form.
HttpClientModule
HttpClientModule is a module that contains an API you can use to send and obtain data for your application from HTTP servers. It is based on the XMLHttpRequest interface. It includes features that enable you to avoid having to extract JSON data, use interceptors to modify request headers, and add interceptors to provider headers.
You can import this module by adding the following to your JSON package file:
xxxxxxxxxx
import {HttpClientModule} from '@angular/common/http';
Reactive forms
Reactive forms enable you to use a model-driven approach for handling form inputs with changing values. With these forms, you can use multiple controls in a form group, validate form values, and construct forms in which you can dynamically modify controls. This is possible because form data is returned as an immutable, observable stream rather than a mutable data point as with template-driven forms.
You can import this module with the following:
xxxxxxxxxx
import {ReactiveFormsModule} from '@angular/forms';
({
imports: [
// other imports ...
ReactiveFormsModule
],
})
export class AppModule { }
How to Implement File Upload in Angular 9: Quick Tutorial
If you’re ready to try implementing file uploads with your Angular application you can try the following tutorial which uses the FormData and the HttpClientModule. This tutorial is adapted from a longer tutorial by Ahmed Bouchefra.
To get started with this tutorial, you’ll need the following:
A file sharing service like file.io or Dropbox
A development environment with Node.js 8.9+ and npm 5.5.1+
The Angular CLI
You can install this globally with npm install -g @angular/cli in your system CLI
1. Create New App and Start Development Server
To get started, you need to first create an application to handle uploads with. You can create a new application by entering the following into your terminal:
xxxxxxxxxx
ng new {Application name}
When you create this, you need to specify whether to add Angular routing (yes) and your stylesheet format (CSS).
Next, you need to start a local development server from your terminal:
xxxxxxxxxx
cd {Application name}
ng serve
This will start a server and return the local host address. Open the returned site in your browser to see your application.
2. Set up HttpClientModule
Initialize your project through the Angular CLI and import the HttpClientModule. To do this, you need to open your src/app/app.module.ts file. You can do this with the following:
xxxxxxxxxx
import {BrowserModule} from '@angular/platform-browser';
import {NgModule} from '@angular/core';
import {AppRoutingModule} from './app-routing.module';
import {AppComponent} from './app.component';
import {HttpClientModule} from '@angular/common/http';
({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
3. Add Control Components and UI
To add UI control components you need to create a home and about components. You can add these in the terminal with the following:
xxxxxxxxxx
cd ~/angular-upload-example
ng generate component home
ng generate component about
To finish the UI, you can either create components manually or use additional modules like Angular Material. Whichever method you choose, you need to at least define your uploadFile() method and provide a button or submission method for your user.
You then need to add your components to your router via the following: src/app/app-routing.module.ts file.
xxxxxxxxxx
import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
import {HomeComponent} from './home/home.component';
import {AboutComponent} from './about/about.component';
const routes: Routes = [
{path: '', redirectTo: 'home', pathMatch: 'full'},
{path: 'home', component: HomeComponent},
{path: 'about', component: AboutComponent},
];
({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
4. Create Your Upload Service
First, you need to create your service with:
xxxxxxxxxx
ng generate service upload
In the src/app/upload.service.ts file, add your imports and inject your HTTP client:
xxxxxxxxxx
import {HttpClient, HttpEvent, HttpErrorResponse, HttpEventType} from '@angular/common/http';
({
providedIn: 'root'
})
export class UploadService {
SERVER_URL: string = "{Server URL}";
constructor(private httpClient: HttpClient) { }
You also need to add your upload method which allows you to call the post method and send data to your upload server.
xxxxxxxxxx
public upload(formData) {
return this.httpClient.post<any>(this.SERVER_URL, formData, {
reportProgress: true,
observe: 'events'
});
}
5. Define Your Upload Method
Once your service is created you need to define your upload method and add error handling. This is also where you can add progress bar elements and change your UI styling if you wish.
In the src/app/home/home.component.ts file, add your imports.
xxxxxxxxxx
import {Component, OnInit, ViewChild, ElementRef} from '@angular/core';
import {HttpEventType, HttpErrorResponse} from '@angular/common/http';
import {of} from 'rxjs';
import {catchError, map} from 'rxjs/operators';
import {UploadService} from '../upload.service';
({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
"fileUpload", {static: false}) fileUpload: ElementRef;files = []; (
constructor(private uploadService: UploadService) { }
Now you can define your method and variables, and inject your upload service.
xxxxxxxxxx
uploadFile(file) {
const formData = new FormData();
formData.append('file', file.data);
file.inProgress = true;
this.uploadService.upload(formData).pipe(
map(event => {
switch (event.type) {
case HttpEventType.UploadProgress:
file.progress = Math.round(event.loaded * 100 / event.total);
break;
case HttpEventType.Response:
return event;
}
}),
catchError((error: HttpErrorResponse) => {
file.inProgress = false;
return of(`Upload failed: ${file.data.name}`);
})).subscribe((event: any) => {
if (typeof (event) === 'object') {
console.log(event.body);
}
});
}
To enable users to submit files, you should also define an onClick() method to be tied to your submit button.
xxxxxxxxxx
onClick() {
const fileUpload = this.fileUpload.nativeElement;fileUpload.onchange = () => {
for (let index = 0; index < fileUpload.files.length; index++)
{
const file = fileUpload.files[index];
this.files.push({ data: file, inProgress: false, progress: 0});
}
this.uploadFiles();
};
fileUpload.click();
}
You can now test your application via the local browser to ensure that it functions as expected.
Conclusion
Hopefully, you now have enough information to experiment with Angular file upload components. If you’re new to the process, make sure to experiment in a test environment, or any place where you can safely learn from your mistakes. Continue experimenting and learning different types of approaches, until you’ll find a mix of methods that work best for you.
Opinions expressed by DZone contributors are their own.
Comments