Native file issues

I can’t seem to find any info on the error I’m getting when trying to copy a file taken with the camera to data storage. Here is my function (which is pretty much what everyone seems to do):

  copyFileToLocalDir() {
    
    let d = new Date();
    let n = d.getTime();
    let newFileName =  n + ".jpg";
    console.log('new name',newFileName);
    
    this.file.copyFile(this.imagePath, this.imageName, cordova.file.dataDirectory, newFileName)
      .then(success => {
        this.lastImage = newFileName;
      }, error => {
        console.log('error saving');
      });
  }

The error I’m getting when running in Android emulator is ERROR Error: Uncaught (in promise): Invalid action
Ionic Info:

cli packages: (/Users/billb/dev/customer-mkt-app/node_modules)

    @ionic/cli-utils  : 1.12.0
    ionic (Ionic CLI) : 3.12.0

global packages:

    cordova (Cordova CLI) : 7.0.1

local packages:

    @ionic/app-scripts : 1.3.7
    Cordova Platforms  : android 6.2.3 ios 4.4.0
    Ionic Framework    : ionic-angular 3.3.0

System:

    Android SDK Tools : 26.1.1
    ios-deploy        : 1.9.0
    ios-sim           : 5.0.10
    Node              : v7.8.0
    npm               : 4.6.1
    OS                : macOS Sierra
    Xcode             : Xcode 9.0 Build version 9A235

Misc:

    backend : legacy

What is this.file?
What line is throwing that error?

This is old and should be upgraded.

this.file… is referencing Native file

import { File } from '@ionic-native/file';
...
  constructor(public navCtrl: NavController, public navParams: NavParams, private StorageProvider: StorageProvider, public viewCtrl: ViewController, private camera: Camera, private file: File, public platform: Platform) {
  }

When I tried to use just File… it would through an error of copyFile not found on typeof File

the line that throws the error is

this.file.copyFile(this.imagePath, this.imageName, cordova.file.dataDirectory, newFileName)

what version is app-scripts up to?

app-scripts is now at 3.0.0

btw, updating app-scripts didn’t resolve the issue

So I had to dig further and better understand what File plugin is doing. And thanks to the answers on these two questions here and here, I finally figured this thing out. Here’s my final code:

 copyFileToLocalDir() {
    let d = new Date();
    let n = d.getTime();
    let newFileName =  n + ".jpg";
    // cordova.file.dataDirectory
    let externalStoragePath: string =  cordova.file.dataDirectory;
    
    this.file.resolveLocalFilesystemUrl(this.imagePath + this.imageName)
      .then((entry: any)=>{
        console.log('entry',entry);
      
        this.file.resolveLocalFilesystemUrl(externalStoragePath)
          .then((dirEntry: any)=>{
            
            entry.copyTo(dirEntry, newFileName, this.successCopy, this.failCopy);
          
          }).catch((error)=>{
            console.log(error);
          });

      }).catch((error)=>{
        console.log(error);
      });

  }

You have to create 2 objects, one of the current file (entry) and one for the path to copy the file to (dirEntry). That was the key to working this out.

1 Like

Hey! I ran into the same problem with ionic 4 and angular.
I tried to adapt your solution to my code but it crashes at

const externalStoragePath: string = cordova.file.dataDirectory;

with

Property 'file' does not exist on type 'Cordova'.

1 Like

In case of angular, you need to inject File into your project:

  constructor(private file: File ) {
     const externalStoragePath: string = cordova.file.dataDirectory;
  }

If you necessarily want to use cordova.file the use it like this:

     const externalStoragePath: string = (cordova as any).file.dataDirectory;