Mastering File Navigation with Ionic Native File

In continuation of the previous tutorial on the Cordova File Navigator, here is the one on the Ionic Native solution.

Don't hesitate to have a look at the other one, there might be some complementary information there.

As usual the installations:

ionic start ionic-native-file-navigation blank ionic cordova plugin add cordova-plugin-file npm install --save @ionic-native/file

Ionic Native File relies on the Cordova Plugin File library so we need both of them.

Once we are good to go, we move to the app.module.ts file to add the File plugin as Provider:

. . . import { File } from '@ionic-native/file' ; @ NgModule ( { . . . providers : [ . . . File ] } ) export class AppModule { }

Accessing The Root Folder

Next is the home.html file:

< ion-header > < ion-navbar > < ion-title > Ionic File Navigation </ ion-title > </ ion-navbar > </ ion-header > < ion-content padding > < button ion-button (click) = " goUp() " > Go up </ button > < div *ngFor = " let item of items " > < div *ngIf = " item.isDirectory " (click) = " goDown(item) " > Directory: {{item.name}} </ div > < div *ngIf = " item.isFile " > File: {{item.name}} </ div > </ div > </ ion-content >

It's the same one as the previous tutorial.

One button to go up and an ngFor that will list our items either as a simple file or a directory that can be explored thanks to a goDown custom method. Once we tap on a directory, the folder information will be passed to this goDown method.

Moving now to the home.ts file:

import { Component } from '@angular/core' ; import { NavController , Platform } from 'ionic-angular' ; import { File } from '@ionic-native/file' ; @ Component ( { selector : 'page-home' , templateUrl : 'home.html' } ) export class HomePage { items ; savedParentNativeURLs = [ ] ; constructor ( public navCtrl : NavController , public fileNavigator : File , public plt : Platform ) { const ROOT_DIRECTORY = 'file:///' ; plt . ready ( ) . then ( ( ) = > { this . listDir ( ROOT_DIRECTORY , '' ) ; } ) } }

This time we need to import and inject the File Service in a fileNavigator property.

The items property will be used to show the files/folders and the savedParentNativeURLs property for keeping in memory the parents as we go deeper.

The ROOT_DIRECTORY constant is set to "file:///", this path allows us to access the root directory on any device.

There are other paths already defined in the fileNavigator property like dataDirectory, externalDataDirectory or externalCacheDirectory, however, those ones can be specific to a device's OS or sandboxed.

Compared to the previous tutorial, only one custom listDir method will be used to list the files in a directory and we will pass the path and directory's name as parameters (more explanation on this later).

As usual the handleError method:

handleError = error = > { console . log ( "error reading," , error ) ; } ;

Here is our listDir method:

listDir = ( path , dirName ) = > { this . fileNavigator . listDir ( path , dirName ) . then ( entries = > { this . items = entries ; } ) . catch ( this . handleError ) ; } ;

We can now use the fileNavigator property 😉.

The listDir is our main method. This built-in method only needs the path to the parent's directory that contains the directory's name we are targeting.

It's a bit weird because it would be simpler to just pass the whole path (maybe it was designed to match another method).

Back to the method's call located in the HomePage constructor:

constructor ( public navCtrl : NavController , public fileNavigator : File , public plt : Platform ) { const ROOT_DIRECTORY = 'file:///' ; plt . ready ( ) . then ( ( ) = > { this . listDir ( ROOT_DIRECTORY , '' ) ; } ) }

Here we have:

The path: 'file:///', this path is the root directory, it will work on any device (iOS, Android, etc) The directory name: Set to '', we don't want to go any deeper, however, we need to pass two arguments to the method hence the empty string

Great! We now receive a Promise with our precious entries and set the items property.

Let's navigate now!

Going Up and Down

Two objectives here:

Moving down and listing the children when a user taps on a directory Allowing the user to go to the parent's directory

The goDown method is as follow:

goDown = item = > { const parentNativeURL = item . nativeURL . replace ( item . name , "" ) ; this . savedParentNativeURLs . push ( parentNativeURL ) ; this . listDir ( parentNativeURL , item . name ) ; } ;

When the user taps on an item in the UI, we acquire this item here.

The current parent directory is stocked in the savedParentNativeURLs property so we can go up later.

This is done by removing the current item's name from the item's nativeURL, here is an example:

name: matthieu nativeURL: file:///Users/matthieu parentNativeURLs: [file: ///Users]

Finally our custom listDir method is called with the parentNativeURL and the item's name. The final method: goUp.

goUp = ( ) = > { const parentNativeURL = this . savedParentNativeURLs . pop ( ) ; this . listDir ( parentNativeURL , "" ) ; } ;

Very simple here, the current parent's url is the last one added to the savedParentNativeURLs array, all we need is a classic pop method to grab it.

Once we have the url, we can call the custom listDir method with the parent's native url and an empty string as the second parameter.

And voila!

We are done:

Conclusion

The Ionic Native File plugin is very simple to use. We only need the listDir method to navigate. This is way simpler than Cordova's window.resolveLocalFileSystemURL or window.requestFileSystem!

In the previous tutorial, Cordova was quite verbosy, but it does work with any technology (Ionic 1, 2, 3) which makes it a stable solution.

One of the most important point in this tutorial is setting “file:///” as root path in order to access the real root directory of a device otherwise we will be stuck in a most likely empty sandboxed folder.