Trying to get an API call to work using JSReport Online



  • Having trouble understanding what I'm missing here - when I show the page from a subdomain of ours and click the button nothing happens. Is the URL correct - does it always look like this and the template name is used to choose what report is to be ran. Is there any way to authenticate access to the report? Just using same example Json - just trying to get the API call to work. I removed [our-unique-code] to share this publically. Do I need to include some code for "jsreport.render" to work?

    Thank you for your time!
    '''
    <html>
    <head></head>
    <body>
    <input type="button" title="test" onclick="generateReport();" value="Get PDF Report"/>
    <div id="placeholder" style="height:900px;"></div>
    <script>
    jsreport.serverUrl = 'https://[our-unique-code].jsreportonline.net/api/report';
    //URL path in which jsreport server runs
    /* For the sample purpose, the below JSON can be used. But in real time this data should come from Web API calls */

    var outputJSON = {
    "employee": "john",
    "address": {
        "streetaddress": "101 E Main Ave",
        "address2": " ",
        "citystzip": "Tucson, AZ 85701"
    },
    "employeephone": "(520)360-1217",
    "employeeemail": "john@zinatt.com",
    "payperiodending": "10/29/2021",
    "rows": [{
        "day": "Week# 44, Mon 10/18/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },
    {
        "day": "Week# 44, Tue 10/19/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },
    {
        "day": "Week# 44, Wed 10/20/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },
    {
        "day": "Week# 44, Thu 10/21/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },{
        "day": "Week# 44, Fri 10/22/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },
    {
        "day": "Week# 45, Mon 10/25/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },
    {
        "day": "Week# 45, Tue 10/26/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },
    {
        "day": "Week# 45, Wed 10/27/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },
    {
        "day": "Week# 45, Thu 10/28/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    },
    {
        "day": "Week# 45, Fri 10/29/21",
        "regularhours": 8,
        "travel": 100,
        "expense": 25.00,
        "casenumber": "John Demo",
        "total": 425.00
    }],
    "rateperhour": 50.00,
    "milecost": 0.52,
    "totalhours": 80,
    "totaltravel": 800,
    "totalexpenses":200.00,
    "totalpay": 4000.00,
    "travelcost": 416.00,
    "grandtotal": 4616.00
    

    }

    function generateReport() {    
    var request = {    
            template: {    
                  name: 'TimeSheet'    
                 },     
                       data: outputJSON    
            };    
    jsreport.render($("#placeholder"), request);     
    // here ”placeholder” is div tag name in html page    
    } 
    

    </script>

    </body>
    </html>
    '''


  • administrators

    hi @John-Backer

    Is the URL correct

    yes, it looks correct.

    does it always look like this and the template name is used to choose what report is to be ran

    yes, the template that is going to be rendered is got from the details of your request, it can be template name, or template shortid, or template _id

    Is there any way to authenticate access to the report?
    Do I need to include some code for "jsreport.render" to work?

    yes, you need to include the authentication part, because jsreportonline is a services you can only access if you are authorized, add this to your code after the jsreport.serverUrl line:

    // URL path in which jsreport server runs
    jsreport.serverUrl = 'https://[our-unique-code].jsreportonline.net/api/report';
    // you need to set your jsreportonline credentials here
    jsreport.headers['Authorization'] = "Basic " + btoa("<yourjsreportonlineemail>:<yourjsreportonlinepassword>") // example: "Basic " + btoa("admin:password")
    

    of course replace this with your real credentials and your request should complete correctly.



  • Thanks for the feedback. I tried implementing what you suggested, but it still doing the same thing...nothing. How do we debug this?


  • administrators

    ah ok, it seems i forgot that the serverUrl should be the root url not the one with /api/report, internally the .render() know what http url to call in the end.

    so please change the serverUrl to just this:

    jsreport.serverUrl = 'https://[our-unique-code].jsreportonline.net';
    

    if that does not work please show what is the error message, it should be available in the browser console.



  • The console is saying that jsreport is not defined.


  • administrators

    jsreport (browser sdk) is not defined in your html page by default, you need to add it, the quickly way to do it is by adding this to your html at the head tag

    <head>
        <script src="https://unpkg.com/jsreport-browser-client-dist@1.3.0/jsreport.min.js"></script>
    </head>
    


  • Ok, getting further, but now I'm getting an error that the $ is undefined...
    jsreport.render($("#placeholder"), request);


  • administrators

    it seems your code assumes that jQuery is loaded too, to avoid loading that extra lib you can update your code to this:

    jsreport.render(document.getElementById('placeholder'), request)
    


  • This thread will give all newbies all they need :)

    That worked, but when it presented an authentication dialog and I provided my admin credentials from my admin account I get:

    Error: Unable to find specified template or user doesnt have permissions to read it: TimeSheet
    at module.exports (/usr/src/app/node_modules/jsreport-core/lib/util/createError.js:11:13)
    at Reporter.createError (/usr/src/app/node_modules/jsreport-core/lib/reporter.js:332:12)
    at AsyncFunction.<anonymous> (/usr/src/app/node_modules/jsreport-templates/lib/templates.js:134:20)

    I imagine I need to clear my browser cache because it isn't give me a chance to enter new credentials...



  • I cleared by browser cache and added a new user with read access to the template...

    Error: Unable to find specified template or user doesnt have permissions to read it: TimeSheet
    at module.exports (/usr/src/app/node_modules/jsreport-core/lib/util/createError.js:11:13)
    at Reporter.createError (/usr/src/app/node_modules/jsreport-core/lib/reporter.js:332:12)
    at AsyncFunction.<anonymous> (/usr/src/app/node_modules/jsreport-templates/lib/templates.js:134:20)

    It looks like I have a folder of TimeSheet and inside that there is another TimeSheet with all the parts of the project...but it won't let me copy all the components up to the first level...


  • administrators

    my bad, please ignore that authentication dialog because is not going to work correctly, I did not remember that using the .render method does not work against servers with authentication enabled.

    you can find the relevant mention to that in the docs here:

    the relevant information there is this:

    it can send only small amount of the input data
    doesn't support sending headers and it won't work with jsreport server with enabled authentication
    the boolen values in the input data are serialized as strings

    so to solve the issue you need to use the .renderAsync, update your generateReport function to this:

    function generateReport() {    
      var request = {    
            template: {    
                  name: 'TimeSheet'    
                 },     
                       data: outputJSON    
            };    
      } 
    
      jsreport.renderAsync(request).then(function(res) {
                var reportUrl = res.toObjectURL()
                var iframe = document.createElement('iframe')
                var placeholder = document.getElementById('placeholder')
    
                iframe.src = reportUrl
                iframe.style.width = '100%'
                iframe.style.height = '100%'
    
                // clear previous iframe content     
                while (placeholder.firstChild) {
                    placeholder.removeChild(placeholder.firstChild);
                }
    
                placeholder.appendChild(iframe)
            }).catch(function (err) {
                console.error('Error while executing render request', err)
            })
    


  • Thanks, I really appreciate all the help.

    I believe I made the changes you indicated, but I'm getting this in the console:

    https://qtis.jsreportonline.net/api/report 404 (Not Found)
    (anonymous) @ VM292:1
    (anonymous) @ jsreport.min.js:2
    _renderAsync @ jsreport.min.js:2
    renderAsync @ jsreport.min.js:2
    generateReport @ TestJSReport.html:123
    onclick @ TestJSReport.html:6
    TestJSReport.html:139 Error while executing render request



  • ok, I figured that one out - it was my directory structure. I think my last error is:

    Mixed Content: The page at '.......' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://jsreportonline.net/sign'. This request has been blocked; the content must be served over HTTPS. Was I supposed to remove the login lines?


  • administrators

    Was I supposed to remove the login lines

    no, everything else mentioned should stay the same, but just to be sure you can also paste here the full code that you have, of course omitting the real username and password of your account

    what is the exact serverUrl are you using?

    i am testing the same code with my account it works ok, without issues


  • administrators

    you should use this at serverUrl:

    jsreport.serverUrl = 'https://qtis.jsreportonline.net'
    // this should be also present, pass your correct credentials
    jsreport.headers['Authorization'] = "Basic " + btoa("<yourjsreportonlineemail>:<yourjsreportonlinepassword>")
    

    and because your template is inside folders, your template name parameter should look like this (notice that it acceps a path to the template)

    var request = {    
            template: {    
                  name: '/TimeSheet/TimeSheet/timesheet'    
                 },     
                       data: outputJSON    
            };    
      } 
    


  • Thank you so much - it is working now!



  • The code you've provided appears to be an HTML page with JavaScript that attempts to generate a PDF report using the jsreport library. Based on the code you've shared, here are a few things to check and consider:

    jsreport Configuration: Ensure that you have properly configured the jsreport.serverUrl variable with the correct URL of your jsreport server. The URL should point to the jsreport server API endpoint.

    Authentication: You mentioned the need for authentication to access the report. If your jsreport server requires authentication, you should handle authentication either through the server itself (using authentication plugins or middleware) or by sending authentication credentials (e.g., API keys or tokens) along with your API request. Make sure your server is set up to authenticate requests properly.

    Template Name: The code specifies a template name 'TimeSheet'. You should make sure that a template with this name exists in your jsreport server. Templates in jsreport are used to define the structure and layout of the generated reports. Ensure that the template name is correct and that it matches an existing template on your jsreport server.

    jsreport.render: The jsreport.render function is used to render the report. Ensure that the generateReport function is being called when you click the "Get PDF Report" button. You can add console.log statements or use browser developer tools to check if the function is being triggered and if any errors are being logged in the console.

    HTML Structure: Ensure that the HTML structure is valid. The generateReport function seems to be using $("#placeholder") to target a <div> element with the id "placeholder" to render the report. Make sure this <div> element exists on your page.

    JavaScript Errors: Check your browser's developer console for any JavaScript errors. Any errors in your JavaScript code can prevent the report from being generated.

    Cross-Origin Requests: If your jsreport server is hosted on a different domain or subdomain, you might encounter cross-origin issues. Make sure that your server allows cross-origin requests from the subdomain where this code is hosted. You may need to configure CORS (Cross-Origin Resource Sharing) settings on your jsreport server.

    Network Requests: Use your browser's network tab in the developer tools to inspect the network requests being made when you click the button. Check if the API request to the jsreport server is being sent and if there are any error responses.


Log in to reply
 

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