render is not a function
-
I've got this:
const jsreport = require('jsreport-client') export default ({ Vue }) => { console.log('loading jsreport') if (process.env.DEV) { jsreport.serverUrl = 'https://pharmacyinformatics.local:3000/v1' } else { jsreport.serverUrl = 'https://pharmacyinformatics.local/server/v1' }// can add username, password after URL Vue.prototype.$jsreport = jsreport }
You can see I'm trying to add it to Vue so that it is accessible on all components. This works for literally a dozen other modules I'm using. I'm following the axios pattern here. But maybe I'm not actually creating an instance of the object? I thought the above did.
I then call it this way (in the same VueJS/Quasar application):
methods: { async renderReport (selectedName, shortID, facName, facAbbv) { let res = await this.$jsreport.render({ template: { shortid: shortID }, data: { reportInfo: { reportName: selectedName, locationName: facName, locationAbbr: facAbbv }, facility: facAbbv } }) let bodyBuffer = await res.body() console.log(bodyBuffer.toString()) } }
The error is this:
"this.$jsreport.render is not a function"
.render should be available per the first code block. I should have one jsreport object at
this.$jsreport
. So I don't know why it can't find it. Note that I do see the 'loading jsreport' console log as found in the first code block.Ideas?
-
const jsreport = require('jsreport-client')
i'm a bit confused, you are trying to use the
jsreport-client
module, that module is the node.js client of jsreport (it runs server side) but i see that you are trying to use it in Vue, are you running your Vue component on server side? i think you are just requiring the bad module probably you want the browser client which is thejsreport-browser-client-dist
package.const jsreport = require('jsreport-browser-client-dist') export default ({ Vue }) => { console.log('loading jsreport') if (process.env.DEV) { jsreport.serverUrl = 'https://pharmacyinformatics.local:3000/v1' } else { jsreport.serverUrl = 'https://pharmacyinformatics.local/server/v1' }// can add username, password after URL Vue.prototype.$jsreport = jsreport }
-
i think it all depends what kind of client do you expect, because each one has a difference usage in code
-
Oh. I didn't realize there was another option. I was just looking at this: https://jsreport.net/learn/nodejs and figured since Vue is built on Node that I had to choose one of those. I'll go take a look at the one you mentioned. I guess the docs are here: https://jsreport.net/learn/browser-client
-
yes, each one has it own docs, since Vue is mostly a client-side technology (browser) then you should use the browser-client
-
Got it working. For anyone using VueJS, you can see what I did below:
<iframe id="reportFrame" ref="reportFrame" style="background-color: white; margin: auto; height: 90%; width: 100%;" > </iframe>
The above is actually in a Quasar q-dialog.
And here is the method where the callback is made:
onShowReport (val) { // console.log('showing report', val) this.showReport = val if (val) { let myThis = this let isPDF = this.isPDF let request = { template: { shortid: this.shortID }, data: { reportInfo: { reportName: this.selectedName, locationName: this.facilityName, locationAbbr: this.facility.value }, facility: this.facility.value } } this.$jsreport.renderAsync(request).then(function (res) { // console.log('Res toString', res.toString()) if (isPDF) { myThis.$refs.reportFrame.type = 'application/pdf' myThis.$refs.reportFrame.src = res.toDataURI() } else { myThis.$refs.reportFrame.type = 'text/html' myThis.$refs.reportFrame.src = res.toDataURI() } // get the content as string // res.toString() // open download dialog // res.download('test.pdf') }) } }
I'm not sure how to set the download filename of the PDF. Presently it shows as 'download.pdf'. I'll open another forum post with that question and one more.
-
I had to change one line:
myThis.$refs.reportFrame.outerHTML = res.toString()
Large data sets were resulting in empty iframes. I'm not sure what res.toDataURI() is doing that wasn't working.