NativeScript + Angular 2 - Download and Open file on iOS
While there is a ton of love about the {N}+ng combo, there seem to be some rough edges as well. This isn't entirely unexpected, as it's a relatively new mobile stack, and one with huge potential.
While trying to use Angular's Http.post(...)
, I continued to run into problems using the Response.arrayBuffer()
or Response.blob()
methods to create a file that NativeScript was able to save/open successfully. So I decided to switch to NativeScript's http.getFile()
method. That, combined with NativeScript's iOS-specific utils.ios.openFile()
method, I was able to easily download, save, and open binary files from a backend.
{N}+ng Component (app.component.ts)
import {Component} from "@angular/core";
import * as http from "http";
import * as fs from "file-system";
import * as utilModule from "utils/utils";
@Component({
selector: "my-app",
templateUrl: "app.component.html",
})
export class AppComponent {
public downloadAndOpenPDF(): void {
let filename: string = 'test.pdf';
let url: string = `https://blog.zgoda.us/content/images/2017/01/${filename}`;
let path: string = fs.path.join(fs.knownFolders.documents().path, filename);
http.getFile({
url: url,
method: "GET"
}, path)
.then(file => {
console.log(`Downloaded File: ${JSON.stringify(file)}`);
if (file && fs.File.exists(file.path)) {
let opened = utilModule.ios.openFile(file.path);
console.log(opened ? 'Opened' : 'Not Opened');
} else {
console.log("File doesn't exist.");
}
})
.catch(error => {
console.log(`getFile error: ${JSON.stringify(error)}`);
});
}
}
Component Template (app.component.html)
<StackLayout class="p-20" verticalAlignment="middle">
<Button text="Download and Open PDF" (tap)="downloadAndOpenPDF()" class="btn btn-primary btn-active"></Button>
</StackLayout>
Using POST
In my real-world problem, I needed to use POST w/ URL encoded values to query my backend API. In this case, the first parameter of http.getFile()
becomes:
{
url: url,
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
content: "key1=value1&key2=value2"
}