How to upload files in Angular

Key takeaways:

  • Create an HTML template with an input of type “file” to allow users to select files.

  • Handle file input in TypeScript by storing the selected file in a variable.

  • Implement a file upload function that uses a file upload service to send the file to the server.

  • Create a file upload service using Angular’s HttpClient to handle the actual file transfer.

  • Use FormData to package the file for upload in the service.

  • Implement best practices such as file type validation, progress indicators, and error handling.

  • Always use secure protocols (HTTPS) for file transfers.

Implementing file uploads in Angular is straightforward. It involves creating an HTML template, handling file input, implementing an upload function, and defining a file upload service. Whether we’re building a document management system or a photo-sharing app, we all need file upload functionality. From setting up the HTML template to implementing the file upload service, this Answer will guide us through creating a file upload component in Angular. But first, let’s look at key takeaways.

Step 1: Creating the HTML template

Let’s start by creating an HTML template for the file upload component.

<h1>File Upload Application</h1>
<div class="form-group">
<label for="file">Upload a file</label>
<input type="file" id="file" (change)="handleFileInput($event)">
</div>
<div *ngIf="fileToUpload">
<h4>File Details:</h4>
<p><strong>Name:</strong> {{ fileToUpload.name }}</p>
<p><strong>Size:</strong> {{ fileToUpload.size }} bytes</p>
<p><strong>Type:</strong> {{ fileToUpload.type }}</p>
</div>
Creating an HTML for file upload (app.component.html)

In the code above:

  • Line 5: We define an input tag of the type file and add a function to the (change)-event to handle the file selection event. This simple template provides a user-friendly interface for selecting files to upload.

  • Lines 8–13: We display the details of the selected file (name, size, and type) using Angular’s interpolation syntax ({{ }}) to bind the values from the fileToUpload object in the component. This block of HTML is only displayed if a file is selected.

Step 2: Handling file input in TypeScript

Next, we’ll define a variable to store the selected file and create a function to handle the file input:

fileToUpload: File | null = null;
handleFileInput(event: Event) {
const input = event.target as HTMLInputElement;
if (input.files && input.files.length > 0) {
this.fileToUpload = input.files.item(0);
} else {
this.fileToUpload = null; // Handle no file selected
}
}
Handling file input in TypeScript (app.component.ts)

In the code above:

  • Line 1: We define a variable fileToUpload in the component class. Initially, it is set to null, indicating that no file has been uploaded yet.

  • Lines 3–10: We define the handleFileInput() method to handle the file selection process by checking if the user has selected a file from the input. Inside this method:

    • Line 4: We cast the event.target to an HTMLInputElement. The target in the Event object refers to the input element where the event was triggered.

    • Lines 5–6: If a file is selected, we set the fileToUpload variable to that file, allowing its details (like name, size, and type) to be used elsewhere in the component.

    • Line 8: We reset the variable to null if no file is selected.

This code ensures that we capture and store the selected file for later use in our upload process.

Step 3: Implementing the file upload function

Now, let’s create a function to initiate the file upload process:

uploadFileToActivity() {
if (this.fileToUpload) {
this.fileUploadService.postFile(this.fileToUpload).subscribe(
(data) => {
console.log('File uploaded successfully');
// Add your success logic here
},
(error) => {
console.error('Error uploading file:', error);
// Add your error handling logic here
}
);
} else {
console.warn('No file selected or invalid file type');
}
}
Implementing the upload function (app.component.ts)

We define the uploadFileToActivity() function to handle the logic of uploading a selected file to the backend using a service. This function calls our file upload service and handles the response, whether a success or an error. In this function:

  • Lines 2–12: On a valid file assigned to the fileToUpload variable, we use the fileUploadService service to handle the actual file upload. We provide feedback for both success (e.g., “File uploaded successfully”) and failure (e.g., error during upload).

  • Line 14: We log a warning to the console to notify the user that the file has been selected incorrectly or is of an invalid type.

Step 4: Defining the file upload service

The file upload service is responsible for sending the file to the server. Here’s how we can implement it using Angular’s HttpClient:

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class FileUploadService {
constructor(private httpClient: HttpClient) { }
postFile(fileToUpload: File): Observable<boolean> {
const endpoint = 'your-destination-url'; // Replace with your backend endpoint
const formData: FormData = new FormData();
formData.append('fileKey', fileToUpload, fileToUpload.name);
return this.httpClient
.post(endpoint, formData, { headers: this.getHeaders() })
.pipe(
map(() => true),
catchError(this.handleError)
);
}
private getHeaders(): HttpHeaders {
return new HttpHeaders();
}
private handleError(error: any) {
console.error('An error occurred:', error);
return throwError('Error uploading file. Please try again.');
}
}
Defining the file upload service (file-upload.service.ts)

In the code above:

  • Lines 1–4: We import the required resources.

  • Lines 6–8: We mark this service as injectable and make it available throughout the application.

  • Lines 9–34: We define the FileUploadService class to define the file upload service. Inside this class:

    • Line 10: We injected the HttpClient through the constructor, allowing HTTP requests to be made within the service.

    • Lines 12–24: We define the postFile() method to handle the process of uploading a file to the backend server and returning an observable that signals the success or failure of the upload operation. It takes one parameter, fileToUpload, which is the file object, and returns an Observable<boolean>. This method specifies the backend URL (endpoint) where the file will be uploaded. We create a new FormData object to package the file for uploading and append it to the form using the key 'fileKey'. We use the httpClient.post() method to send a POST request to the specified endpoint.

    • Lines 26–28: We define the getHeaders() method to provide any necessary HTTP headers for the file upload request. The method returns an HttpHeaders object, which is currently empty but can be customized to include headers (e.g., for authentication or content type).

    • Lines 30–33: We define the handleError() method to handle any errors during file upload. It takes one parameter, error, which can be any error, and returns an Observable<never>. Inside this method, we log the error to the console for debugging purposes. We use throwError() to return an error message, such as 'Error uploading file. Please try again.', which can be displayed in the UI.

Application demo

Let’s run the complete application in the following playground.

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError, map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class FileUploadService {
  constructor(private httpClient: HttpClient) { }

  postFile(fileToUpload: File): Observable<boolean> {
    const endpoint = 'your-destination-url'; // Replace with your backend endpoint
    const formData: FormData = new FormData();

    formData.append('fileKey', fileToUpload, fileToUpload.name);

    return this.httpClient
      .post(endpoint, formData, { headers: this.getHeaders() })
      .pipe(
        map(() => true),
        catchError(this.handleError)
      );
  }

  private getHeaders(): HttpHeaders {
    return new HttpHeaders();
  }

  private handleError(error: any) {
    console.error('An error occurred:', error);
    return throwError('Error uploading file. Please try again.');
  }
}
Code example of the file upload functionality in the Angular app

Best practices and error handling

When implementing file uploads, consider the following best practices:

  • Validate file types and sizes before uploading.

  • Implement progress indicators for large file uploads.

  • Use secure protocols (HTTPS) for file transfers.

  • Implement proper error handling and user feedback.

Here’s an example of how we might add file type validation:

validateFile(file: File): boolean {
const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf'];
if (!allowedTypes.includes(file.type)) {
console.error('Invalid file type');
return false;
}
return true;
}
An example of the validateFile method in Angular

Note: Remember to always consider security implications when handling file uploads, and implement proper error handling and user feedback to ensure a smooth user experience.

Frequently asked questions

Haven’t found what you were looking for? Contact Us


How do I upload a file with Angular?

To upload a file with Angular:

  1. Create an HTML template with a file input element.
  2. In the component, create a function to handle the file selection event.
  3. Implement a file upload service using HttpClient.
  4. Create a function in your component to call the upload service when ready to upload.
  5. Handle the response from the server, including success and error scenarios.

How to upload a PDF file in Angular?

To upload a PDF file in Angular:

  1. Follow the same steps as for any file upload.
  2. In the file type validation, ensure that application/pdf is an allowed MIME type.
  3. You may want to add a specific check in the validation function:
validateFile(file: File): boolean {
  if (file.type !== 'application/pdf') {
    console.error('Invalid file type. Please select a PDF.');
    return false;
  }
  return true;
}

How to make file upload mandatory in Angular?

To make file upload mandatory:

  1. Add the required attribute to your file input in the HTML template.
  2. In the component, check if a file has been selected before allowing form submission or upload.
  3. Provide user feedback if they try to submit without selecting a file.
uploadFile() {
  if (!this.fileToUpload) {
    alert('Please select a file before uploading.');
    return;
  }
  // Proceed with upload...
}

How to upload large files using Angular?

For large file uploads in Angular:

  1. Implement a chunked upload strategy to split the file into smaller pieces.
  2. Use a library like ng2-file-upload that supports chunked uploads.
  3. Implement progress tracking to keep the user informed:
postFile(fileToUpload: File): Observable<any> {
  const formData: FormData = new FormData();
  formData.append('file', fileToUpload, fileToUpload.name);

  return this.http.post('your-upload-url', formData, {
    reportProgress: true,
    observe: 'events'
  }).pipe(
    map((event) => {
      switch (event.type) {
        case HttpEventType.UploadProgress:
          const progress = Math.round(100 * event.loaded / event.total);
          return { status: 'progress', message: progress };
        case HttpEventType.Response:
          return event.body;
        default:
          return `Unhandled event: ${event.type}`;
      }
    })
  );
}
  1. Consider implementing server-side support for resumable uploads in case of connection interruptions.

Remember to always handle errors gracefully and provide clear feedback to the user throughout the upload process.


Free Resources

Copyright ©2025 Educative, Inc. All rights reserved