I know of a similar question to this one: Pdf.js: rendering a pdf file using a base64 file source instead of url. That question was awesomely answered by Codetoffel but my question is different in that my PDF is retrieved via a RESTful call to my Web API implementation. Let me explain...
First, here's a basic way to use PDF.JS to open a PDF via a URL:
PDFJS.getDocument("/api/path/to/my.pdf").then(function (pdf) {
pdf.getPage(1).then(function (page) {
var scale = 1;
var viewport = page.getViewport(scale);
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
page.render({canvasContext: context, viewport: viewport});
});
});
This works great, but I am using Angular and its $resource
service to make the request for the PDF via my RESTful Web API. I do know that PDF.JS allows me to replace passing the URL as a string in the PDFJS.getDocument method (above) with a DocumentInitParams
object, which is defined here. Using the DocumentInitParams object works as follows:
var docInitParams = {
url: "/api/path/to/my.pdf",
httpHeaders: getSecurityHeaders(), //as needed
withCredentials: true
};
PDFJS.getDocument(docInitParams).then(function (pdf) {
...
});
This also works, but it works around my Angular $resource
by requiring me to construct the api URL. But that's OK because PDFJS allows me to give it the PDF data directly, instead of giving it a URL to the PDF, as follows:
var myPdf = myService.$getPdf({ Id: 123 });
//It's an Angular $resource, so there is a promise to be fulfilled...
myPdf.$promise.then(function() {
var docInitParams = {
data: myPdf
};
PDFJS.getDocument(docInitParams).then(function (pdf) {
...
});
});
This is the one I can't seem to get to work. I can tell the myService.$gtPdf
method to return the data as a blob
or as an arraybuffer
but neither works. I've tried to convert the arraybuffer returned data to an Uint8Array
too, but to no avail.
I'm not sure what else to try and could really use a tip.
How do I get the data returned from my service to work with PDFJS?
Thanks in advance.
You're not passing the response data to PDF.js, but an instance of the resource:
var myPdf = myService.$getPdf({ Id: 123 });
myPdf.$promise.then(function() {
var docInitParams = {
data: myPdf
You haven't shown your code for $getPdf
, but I guess that it is something equivalent to
var myService = $resource('/foo', {}, {$getPdf:{responseType: 'arraybuffer'}});
var myPdf = myService.$getPdf();
By default, an AngularJS $resource
treats the response as an object (deserialized from JSON) and copies any properties from the object to the resource instance (myPdf
in the previous snippet).
Obviously, since your response is an array buffer (or Blob, typed array or whatever), this is not going to work. One of the ways to get the desired response is to use transformResponse
to wrap the response object in an object:
var myService = $resource('/foo', {}, {
$getPdf: {
responseType: 'arraybuffer',
transformResponse: function(data, headersGetter) {
// Stores the ArrayBuffer object in a property called "data"
return { data : data };
}
}
});
var myPdf = myService.$getPdf();
myPdf.$promise.then(function() {
var docInitParams = {
data: myPdf.data
};
PDFJS.getDocument(docInitParams).then(function (pdf) {
// ...
});
});
Or simply the following (avoided unnecessary local variables):
myService.$getPdf().$promise.then(function(myPdf) {
PDFJS.getDocument({
data: myPdf.data
}).then(function (pdf) {
// ...
});
});