View External PDF or IMAGE in app (from a web url)

I would like to view PDFs from a URL within the app, the same way you can view PDFs which have been saved to a DB object in the display-image component. Is this possible with the latest PDF updates container 4.80?

Hi Martin

This is not possible at the moment, unfortunately. (Basically this has to do with modern Browsers having built-in PDF readers, but the app does not)

You will need direct access to the PDF files / data in the app if you want to view them in the app.

You can make a suggestion on our roadmap to include the ability to view PDFs in-app from app accessible URLs

@martin Good news - this is now possible

In essence you need to create a JourneyApps attachment in memory and then view that attachment using the new journey.viewFile method. Below is an example for both a PDF and an Image

// PDF Example
function viewRemotePDF() {
     var url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
     return fetch(url, {
        method: "GET",
        mode: 'no-cors',
        browserFetch: true,
    }).then(function(response){
        return response.arrayBuffer();
    }).then(function(response) {
        var attachment = Attachment.create({
            filename: "example.pdf",
            mediaType: "application/pdf",
            data: response
        });
        journey.files.viewFile(attachment);
    });
}
// IMAGE Example 
function viewRemoteImage() {
    var url = "https://docs.journeyapps.com/static/get-started/images/67afa6r-app-view.png"
    return fetch(url, {
        method: "GET",
        mode: 'no-cors',
        browserFetch: true,
    }).then(function(response){
        return response.arrayBuffer();
    }).then(function(response) {
        var attachment = Attachment.create({
            filename: "example.png",
            mediaType: "image/png",
            data: response
        });
        journey.files.viewFile(attachment);
    });
}

Hi Tielman

Thanks, it works great. Just 2 things I noticed while testing.

  1. I could not download the file from the PDF viewer (I would still like this functionality).
  2. I could not open any dialog boxes on the same view, after having called journey.files.viewFile(pdf_attachment).

Regards,

Martin

Hey Martin

If you want to access dialog boxes and Download the file, or make use of any other standard Journey View components, then you will need to use the normal <display-file> component and bind the attachment that is created in JS to a View Variable or a field in the DB, you will not be able to simply access it from memory as is the case in my example.

The ability to download from the journey.viewFile interface does make sense as a feature request though, so I will add it to the backlog

Hi Tielman

I meant that there is a bug. Dialog boxes on the same page refuse to open again after having viewed (and closed) any PDF using journey.viewFile.
I literally have to go back out of the view and back into the view again to get dialog boxes working again.

Regards,
Martin

Oh wow. Can you please send us a support ticket with the details? Ideally a link to an app with steps to reproduce? We can also just try to recreate it on our end, but if you’ve already done that then that will be a lot faster.

UPDATE: The original solution only works on Desktop

Updated implementation via CloudCode works across all platforms
View JS


function preViewImageDirect() {
    var params = {
        url: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
    }
    var data = CloudCode.callTask('getData', params)
    var attachment = Attachment.create({
        filename: "example.pdf",
        mediaType: "application/pdf",
        base64: data
    });
    journey.files.viewFile(attachment);
}

CloudCode

export async function run(params) {
    // Your code here
    var url = params && params.url ? params.url : "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";
    var response = await fetch(url, {method: "GET", mode: 'no-cors'});
    var buffer = await response.buffer();

    // return data
    return buffer.toString('base64');      
}