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?


  • administrators

    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 the jsreport-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 
    }
    

  • administrators

    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


  • administrators

    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.


Log in to reply
 

Looks like your connection to jsreport forum was lost, please wait while we try to reconnect.