Skip to main content

Downloading

Managing PDF and other files is a common task in an application and depending on the task you may need various plugins to accomplish your needs. This tutorial is applicable for PDFs, Images or any file types.

This tutorial covers:

You can try out these features in this sample repository.

Downloading Options

There are various ways you could download a file in a Capacitor app:

  1. Use the fetch API
  2. Use a library like Axios or Angular's HTTPClient
  3. Use the Capacitor HTTP plugin
  4. Use the Capacitor Filesystem plugin DownloadFile method

However, there are some caveats to some of these approaches:

  • Using fetch, Axios or HttpClient require the right CORS setup to allow downloading the PDF.
  • Capacitor HTTP is limited by the amount of memory on the device to download and write a Base 64 encoded PDF. It also does not have a way to indicate progress of download.

Best Way to Download

The best approach is to use the Capacitor Filesystem plugin, and it's DownloadFile method.

Below we download the file from a url, setting path to the filename we want the file to be stored as on the device.


_10
import { Directory, Filesystem } from '@capacitor/filesystem';
_10
_10
...
_10
_10
const { path } = await Filesystem.downloadFile({
_10
directory: Directory.Cache,
_10
path: 'mypdf.pdf',
_10
url
_10
});

When it has downloaded the file it will return the path. This can be used to share the PDF or open it.

Download Progress

To display a progress indicator in the UI we can use the ion-progress-bar Ionic component:


_10
@if (downloading) {
_10
<ion-progress-bar [value]="progress"></ion-progress-bar>
_10
}

In this Angular 17 example we display the progress bar only if we are downloading. We need to set the value property to a value between 0 and 1 which is done using the progress event:


_10
import { NgZone } from '@angular/core';
_10
...
_10
constructor(ngZone: NgZone) {
_10
Filesystem.addListener('progress', (progressStatus) => {
_10
ngZone.run(() => {
_10
this.progress = progressStatus.bytes / progressStatus.contentLength;
_10
});
_10
});
_10
}

You will notice that in this Angular Component:

  • We use ngZone to tell Angular that the we are making changes to something in the view (the progress variable). This is only needed for Angular as events that are emitted from Capacitor are not captured by Angular.
  • We calculate the progress by dividing bytes by contentLength from the ProgressStatus object that is given when the progress event occurs.

Next, we'll need to modify our downloadFile method to make sure it is emitting its progress by setting progress to true:


_10
this.downloading = true;
_10
_10
const { path } = await Filesystem.downloadFile({
_10
directory: Directory.Cache,
_10
progress: true,
_10
path: 'mypdf.pdf',
_10
url,
_10
});
_10
_10
this.downloading = false;

You can try out the downloadFile features in this sample repository.