File plugin

Hello,
I am trying to use File Plugin (File API Plugin for Read and Write File Access on Devices) to open a local file in my project (the file is located in assets folder).

app.module.ts

(...)

// File Plugin
import { File } from '@ionic-native/file/ngx';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule],
  providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    File],
  bootstrap: [AppComponent],
})
export class AppModule {}

tab1.page.ts

import { File } from '@ionic-native/file/ngx';
(...)

  constructor(
(...)
    private file: File) {}

  openLocal(){
    let filePath = this.file.applicationDirectory';

    console.log(filePath);
    
  }

tab1.page.html

(...)

  <ion-button expand="full" (click)="openLocal()">Open PDF</ion-button>
(....)

Console returns NULL for “filePath” (this.file.applicationDirectory’).

I am using:

Ionic CLI : 5.4.16
Ionic Framework : @ionic/angular 6.0.1
@angular-devkit/build-angular : 13.0.4
@angular-devkit/schematics : 13.0.4
@angular/cli : 13.0.4
@ionic/angular-toolkit : 5.0.3

Capacitor:

Capacitor CLI : 3.3.3
@capacitor/core : 3.3.3

Utility:

cordova-res (update available: 0.15.4) : 0.15.3
native-run : 1.5.0

System:

NodeJS : v16.13.1
npm : 8.1.2
OS : macOS Monterey

I will be grateful for your comments.

1 Like

/assets/ isn’t a real folder. It’s built into your app binary. The only way you can access things within it is via HTTP, the same way your app’s code is loaded. No plugin will be of use here.

I am also trying HTTP:

app.module.ts

Included

import { HttpClientModule } from '@angular/common/http';
@NgModule({
...
imports: [HttpClientModule,
...

tab1.page.ts
Included

import { HttpClient } from '@angular/common/http';
...
  constructor(private http: HttpClient) {}

openFile(){
    const t = this.http.get('/assets/file.pdf').subscribe((x)=>{
      console.log(x);
    });
  }

tab1.page.html

<ion-button (click)="openFile()" expand="full">
    OPEN PDF
</ion-button>

After click on button chrome console returns:

core.mjs:6484 ERROR 
HttpErrorResponse {
headers: HttpHeaders, 
status: 200,
 statusText: 'OK', 
url: 'http://localhost:8100/assets/file.pdf', 
ok: false, …
}
error: {error: SyntaxError: Unexpected token % in JSON at position 0 at JSON.parse (<anonymous>) at XMLHtt…, text: '%PDF-1.3\n%���������\n3 0 obj\n<< /Filter /FlateDecod…cc7ce855f52f38fcf5b> ] >>\nstartxref\n144438\n%%EOF\n'}
headers: HttpHeaders {normalizedNames: Map(0), lazyUpdate: null, lazyInit: ƒ}
message: "Http failure during parsing for http://localhost:8100/assets/file.pdf"
name: "HttpErrorResponse"
ok: false
status: 200
statusText: "OK"
url: "http://localhost:8100/assets/file.pdf"
[[Prototype]]: HttpResponseBase

How could I proceed to open the pdf file (ios and Android)?

I solved using Document-Viewer (Document Viewer | Cordova Plugin Document Viewer for PDF Files).
The problem was in the path of the .pdf file, which should be this.document.viewDocument(’…/…/…/assets/file.pdf’, ‘application/pdf’, options); NOT this.document.viewDocument(’/assets/file.pdf’, ‘application/pdf’, options);

On real device this didn’t work.

I am trying with Httpclient and Document Viewer as below:

 openPdf() {
    const options: DocumentViewerOptions = {
      title: 'My PDF'
    };

    this.httpClient.get("assets/file.pdf", {
      observe: 'response',
      responseType: 'blob'})
      .subscribe(response => {
        this.document.viewDocument(response.url, 'application/pdf', options);
      });
  }

Iphone emulator returns error:

[error] - Error in SitewaertsDocumentViewer.viewDocument(): 
 {"message":"invalid file url 'capacitor://localhost/assets/file.pdf' or 
no viewer for mime type 'application/pdf'","details":{"status":0}}

But file path ‘http://localhost:8100/assets/file.pdf’ works on Chrome, it is correct.

Document Viewer works when I use iPhone emulator and absolute path from file (such as /Users/usuer/app/src/assets/file.pdf), showing that Document Viewer is working.

Any suggestion?

I know nothing about this DocumentViewer plugin, and its source website indicates that it’s unmaintained. The Blob result should come back in the HttpResponse body, so whatever library you end up using to hand the Blob to should probably look there instead of the url.

This works (iPhone emulator and device)

ngOnInit() {
      this.httpClient.get('/assets/file.pdf', { responseType: 'blob'})
      .subscribe(res => {
        const reader = new FileReader();
        reader.onloadend = () => {
          this.pdf = reader.result;
        }
        reader.readAsDataURL(res);
        this.url = URL.createObjectURL(res);
      });
  }
    <ion-button href="{{url}}">
          <ion-icon name="create-outline"></ion-icon>
    </ion-button>

The file.pdf is loaded in webview correctly. I don’t know how to go back to the previous page. Pdf covers all webview and there are no button.
How can I go back?

Finally, I got it… I used HTTP and Ionic Native - In App Browser.


import { InAppBrowser, InAppBrowserOptions } from '@ionic-native/in-app-browser';
import { HttpClient } from '@angular/common/http';
…

options : InAppBrowserOptions = 
    { 
        toolbar : 'yes',
        toolbarposition: 'top' ,
    };

…

constructor(
    private iab: InAppBrowser, 
    private http: HttpClient)
{}
…

ngOnInit()
    {
        this.httpClient.get('/assets/file.pdf', { responseType: 'blob'})
          .subscribe(res => {
           const reader = new FileReader();
           reader.onloadend = () => { }
           reader.readAsDataURL(res);
           this.url = URL.createObjectURL(res);
      });
    }
…
openPdf()
    {
        this.iab.create( this.url, "_blank", this.options );
    }