I recently worked on a PDF export feature for our Ember.js web app. There’s some interesting plumbing involving Active Job and PDFKit, but today’s story is about the interaction of wkhtmltopdf with Ember apps.
wkhtmltopdf is a headless browser that, given a URL, spits out a PDF. The problem we encountered is that wkhtmltopdf didn’t recognize when our Ember app was done loading, and thus at a good point to save the PDF.
As a result, we’d get a PDF of the app’s loading screen, like this:
Checking out the command line options, the
Then I saw the
--window-status option. Perfect! When you’re ready for wkhtmltopdf to do its thing, just set
window.status = 'readyToPrint';
So here’s the meat of the problem: Where’s the right place to do this in an Ember app?
Before you read on to my solution, if you’re interested in figuring this out yourself, you can try it out with this jsbin:
wkhtmltopdf window-status readyToPrint http://output.jsbin.com/yihica#/docs/1
This example demonstrates the main hurdle we encountered: Ember’s loading routes. For full credit, your solution should also permit wkhtmltopdf to grab good PDFs of all four pages:
We tried a few approaches before arriving at this. Our current implementation observes the currentPath property on the
ApplicationController to discover when the app is done loading and then performs the side effect afterRender:
App.ApplicationController = Ember.Controller.extend settleDown: (-> if @get('currentPath').indexOf('loading') == -1 Ember.run.scheduleOnce 'afterRender', @, => window.status = 'readyToPrint' ).observes('currentPath')
I suspect there may be other (better?) approaches, but this works reliably for all the pages we need to print. How would you do it?