0
votes

The development environment

cju:~/Projects/ionic2/i2ts $ ionic info
WARN: ionic.config.js has been deprecated, you can remove it.
Your system information:
Cordova CLI: 6.1.1
Gulp version: CLI version 3.9.1
Gulp local: Local version 3.9.1
Ionic Framework Version: 2.0.0-beta.6
Ionic CLI Version: 2.0.0-beta.25
Ionic App Lib Version: 2.0.0-beta.15
ios-deploy version: 1.8.5
ios-sim version: 5.0.8
OS: Mac OS X El Capitan
Node Version: v4.4.2
Xcode version: Xcode 7.3 Build version 7D175

The issue

I tried both on browser platform and ios phone. To see it on browser platform, do the following

ionic platform add brower

ionic run browser

On the browser, it starts with the "Hello Ionic" page. Click the 'Write to local file using cordova-plugin-file' button, on the back, "This is new text" will be written to a local file using cordova-plugin-file. Click the 'Read from file using cordova-plugin-file' button, the console log shows the file is read back. However, the view is not updated. Click any button again, the view will be updated with the new text.

I googled and found a related issue https://github.com/angular/zone.js/issues/137. That says FileReader in cordova-plugin-file is not zoned. But I am using "ionic-angular": "2.0.0-beta.6" in my project. Should not it include the fix already. Still I see the same issue 137 in my ionic2 project.

The code is at https://github.com/CharlesJu1/FileReaderNotZoned

Here is the hello-ionic.ts file.

import {Page} from 'ionic-angular';

declare var window: any;
declare var LocalFileSystem: any;

@Page({
  templateUrl: 'build/pages/hello-ionic/hello-ionic.html'
})
export class HelloIonicPage {

  showText: string = 'Initial text string';

  writeText() {
    var newText = 'This is new text';
    function overWriteFile(fileEntry, dataObj) {
      // Create a FileWriter object for our FileEntry.
      fileEntry.createWriter(function(fileWriter) {

        fileWriter.onwriteend = function() {
          fileWriter.seek(0);
          fileWriter.write(dataObj);
        }

        //truncate() will call onwriteend.
        fileWriter.truncate(0);
      });
    }
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
      console.log('file system open: ' + fs.name);
      fs.root.getFile("newPersistentFile.txt", { create: true, exclusive: false }, function(fileEntry) {
        console.log("fileEntry is file?" + fileEntry.isFile.toString());
        overWriteFile(fileEntry, newText);
      }, function(error) { });
    }, function(error) { });
  }

  test() {
    var that = this;
    var update = function() {
      that.showText = 'This is test text not from local file';
    }

    setTimeout(update, 1000);
  }

  readText() {
    var that = this;  
    var readFile = function(fileEntry, readFileCb) {

      fileEntry.file(function(file) {
        var reader = new FileReader();
        reader.onloadend = function() {

          //this in the following points to fileEntry.file
          console.log("Successful file read: " + this.result);
          readFileCb(this.result);
        };

        reader.readAsText(file);
      }, () => { console.log('Error reading file ') });
    }

    var readFileCb = function(fileContent: string) {
        that.showText = fileContent;
        console.log('readFileCb: ' + that.showText);
    }

    //check https://github.com/apache/cordova-plugin-file for details
    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {

      console.log('file system open: ' + fs.name);
      fs.root.getFile("newPersistentFile.txt", { create: false }, function(fileEntry) {

        console.log("fileEntry is file?" + fileEntry.isFile.toString());
        // fileEntry.name == 'someFile.txt'
        // fileEntry.fullPath == '/someFile.txt'
        readFile(fileEntry, readFileCb);
      }, function(error) { });
    }, function(error) { });
  }
}

Here is the hello-ionic.html file.

<ion-navbar *navbar>
  <button menuToggle>
    <ion-icon name="menu"></ion-icon>
  </button>
  <ion-title>Hello Ionic</ion-title>
</ion-navbar>


<ion-content padding class="getting-started">
  <p> 
    {{showText}}
  </p>

  <button (click)="writeText()">
  Write to local file using cordova-plugin-file
</button>

<br>
<button (click)="readText()">
  Read from file using cordova-plugin-file
</button>

<button (click)="test()">
  Set the text with a timer
</button>


</ion-content>
1

1 Answers

1
votes

There were some known issues in beta-5 and beta-6 around Zones. A new beta should be out soon that resolves them, but in the meantime can you do these steps:

  1. Import NgZone
  2. Inject instance of NgZone
  3. Wrap call where you want data binding to work in the NgZone instance's run method.

See an example here:

https://github.com/danbucholtz/ionic2-weight-tracker/blob/master/app/pages/photo-list/PhotoList.ts#L78

Thanks, Dan