Angular File Upload Tutorial with Example

Posted on

Welcome to our quick Angular file uploads tutorial. You may build a social media platform, collaborative document editing platform, or e-commerce site. We often need to upload files from web clients to our servers. This could be profile pictures, product photos, documents, or any other files.

Today, we’ll look at how we can do that using Angular. But before we start, feel free to review our HTML File Upload Tutorial to see how basic file uploads are done.

Sending files to the server usually involves sending an HTTP POST multipart request. In a multipart request, the Content-Type header is set to multipart/form-data, and files are delimited by optional boundary parameters. The actual file is sent as a binary block of data.

This differs slightly from a regular REST post request where the Content-Type header is usually set to application/JSON.

So, let’s dive into the code; we’re starting with a blank angular project with Bootstrap for styling.

Import the HttpModule in app.module.ts

We’ll need the following imports in the App Module for the next steps to work.

@NgModule({
 declarations: [
   AppComponent
 ],
 imports: [
   BrowserModule,
   AppRoutingModule,
   FormsModule, // required for input file change detection
   ReactiveFormsModule,
   HttpClientModule, // this is required for the actual http request
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }

Make upload button and change event in app.component.html

<div class="container">
 <div class="row mt-5">
   <div class="col-md-4">
     <div class="mb-3">
       <label for="formFile" class="form-label">Upload file example</label>
       <input (change)="this.onFilechange($event)" class="form-control" type="file" id="formFile">
       <button (click)="this.upload()" type="button" class="btn btn-primary mt-3">Upload</button>
     </div>
   </div>
 </div>
</div>

We need to pass the (change) event to our ts file so we can get the file content. Actual upload is triggered by the upload button in this example, but it’s up to your application logic.

Detect file change in angular

In Angular, it’s considered a best practice to offload network-related operations to another service. So in the app component, we merely wait for the upload button click, and forward the selected file to the upload service.

app.component.ts

import { UploadService } from './upload.service';
import { Component } from '@angular/core';
 
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 
 file: File = null;
 
 constructor(
   private uploadService: UploadService
 ){
 
 }
 
 onFilechange(event: any) {
   console.log(event.target.files[0])
   this.file = event.target.files[0]
 }
 
 upload() {
   if (this.file) {
     this.uploadService.uploadfile(this.file).subscribe(resp => {
       alert("Uploaded")
     })
   } else {
     alert("Please select a file first")
   }
 }
}

Create a service for the network calls

This service actually takes care of the upload process.

upload.service.ts

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
 
@Injectable({
 providedIn: 'root'
})
export class UploadService {
 
 constructor(
   private httpClient: HttpClient,
 ) { }
 
 public uploadfile(file: File) {
   let formParams = new FormData();
   formParams.append('file', file)
   return this.httpClient.post('http://localhost:3000/uploadFile', formParams)
 }
}

Here, we’re making a post request to our backend operating on http://localhost:3000 to the path of /uploadFile path.

FormData is not an angular-specific component, it represents an HTTP form submission in vanilla Js also. The Angular HttpClient accepts this as a valid argument for the body of the HTTP request.

angular file upload response

As you see, this creates a multipart request with our file in the body.

You can see how to receive and parse the file from the body of the request on a NodeJs server running expressJs in our NodeJS tutorial.

When embarking on implementing file uploads in Angular, there are a few key points to think about. Beyond the basic steps covered in this article, delving into additional major and minor concepts can significantly enhance your understanding and capabilities. These concepts not only expand your knowledge but also empower you to create more efficient, user-friendly, and optimized file upload functionalities within your Angular applications. Let’s explore these concepts in greater detail to ensure your file upload implementation is robust, responsive, and aligned with best practices.

Uploading Files with Observables

Angular’s focus on reactive programming is a powerful paradigm for managing asynchronous operations. In the context of file uploads, leveraging observables enhances the application’s responsiveness and maintainability.

Reactive Event Handling

Reactive programming using observables allows for elegant event handling and data flow management. Instead of traditional imperative event listeners, the (change) event for file selection in the article’s tutorial can be transformed into an observable stream. This enables developers to apply various operators, such as debounceTime or switchMap, to control the timing and sequencing of events. Reactive event handling ensures efficient utilization of resources and a more streamlined user experience during file uploads.

Progress Tracking and Error Handling with Observables

Observables extend beyond basic event handling by enabling comprehensive progress tracking and error handling during file uploads. By wrapping the HTTP request in an observable, developers can subscribe to events that provide updates on upload progress. This allows for real-time feedback to users through progress bars or notifications. Furthermore, observables make it convenient to handle errors by using the catchError operator to gracefully manage failed uploads and provide meaningful error messages to users.

 

Optimizing Performance with Lazy Loading and Code Splitting

As Angular applications grow in complexity, optimizing performance becomes crucial. Lazy loading and code splitting are strategies that significantly improve loading times and resource usage, especially in scenarios involving file uploads.

Lazy Loading Modules

Angular’s lazy loading enables the loading of specific modules only when they are needed. In the context of file uploads, this means that the components and services related to uploading files can be encapsulated within a separate module. By doing so, these resources are loaded on demand, reducing the initial load time of the application. Lazy loading modules also contribute to more efficient memory usage as resources are allocated only when required.

Code Splitting for Smaller Bundles

Code splitting is closely related to lazy loading and involves breaking down the application’s codebase into smaller, manageable chunks, or bundles. When a user accesses a specific feature, only the relevant bundle is loaded, leading to faster initial loading times. In the context of file uploads, code splitting ensures that the components and services associated with file handling are isolated from other parts of the application, resulting in a more optimized and responsive user experience.

And there you have it! Your very own file upload tool for your Angular applications. If you’re planning to make one that’s specific to images, then check out this Angular image uploader API tutorial


Read More →

Ready to get started?

Create an account now!