ChartJs not rendering in my angular application



  • I've got an example working in the jsreport studio. Sample code here.. https://playground.jsreport.net/studio/workspace/rkaXqMXWf/2 I am using html-with

    I have a console.log (inside the report template) on line 12, which I see when I'm in jsreport studio RUN, but I don't see when I'm in my app, so that part is not getting executed.

    I do see the html call resolve and I get the "... Hello World ..." (from the report template) in my angular app. Using Chrome Devtools I do see the space for the chart, but it is empty.

    This is the angular code block of relevance. It works fine for normal reports. Should I be doing something different?

      onDataReady(data: any) {
        const self = this ;
        console.log("onDataReady", data);
    
        // build up parms
        const requestParms = {
          "template": {
            name: this.reportTemplate,
            recipe: this.recipe
          },
          "data": data
        };
    
        // send API call to server
        this.appInfo.jsreport.renderAsync(requestParms)
          .then(function (res) {
            // goood response, attach to the innerHtml of the div (angular's way of grabbing the html element)
            const mydiv2 = self.rptsection.nativeElement;
            mydiv2.innerHTML = res.toString();
          }).catch(function(err){
            console.log("Error in jsReport.renderAsync:", err) ;
        });
      }
    

  • administrators

    since your jsreport output is more like a whole html page (it has its own body tag), maybe you should load the html in an iframe, something like this.

    // send API call to server
        this.appInfo.jsreport.renderAsync(requestParms)
          .then(function (res) {
            // goood response, attach to the innerHtml of the div (angular's way of grabbing the html element)
            const mydiv2 = self.rptsection.nativeElement;
            const iframeEl = document.createElement('iframe')
      
            mydiv2.innerHTML = '';
            mydiv2.appendChild(iframeEl);
    
            iframeEl.contentWindow.document.write(res.toString());
          }).catch(function(err){
            console.log("Error in jsReport.renderAsync:", err) ;
        });
    

    this should make it work, or maybe angular is not letting you insert html that contains script tags, it is probably being escaped or something, you should check that in angular docs, how it handles raw html, maybe it has some conflicts with this way.


  • administrators

    make sure to read this topic, which contains relevant information about angular security with the DOM



  • What I have is a Report Container Component, it's not a whole page. It works given that it is a regular report. Now, correct me if I'm wrong, but doesn't the res.toString contain a script tag for a basic report? I was under the impression that there is and is executing. (I can understand if it doesn't actually execute because of the angular security).

    So what I have works for a normal report. When it turns into an issue is when the report itself contains a script and that inner script doesn't appear to execute.

    I guess my question is, is that script tag that comes in the res.toString() executing? (I apologize for my lack of experience).


  • administrators

    I guess my question is, is that script tag that comes in the res.toString() executing? (I apologize for my lack of experience).

    yes, res.toString() will give you the html that you defined in the report, including the scripts tags, so at the time when you insert that content in your mydiv2 element then it should execute the script tags normally, because you are just insert it into the page, if it is not executing it then maybe it is a problem with angular, check your console, maybe there is some error message there, also try to do a console.log(res.toString()) just to verify that you are receiving an html string.



  • For the next guy...

    As it turns out the script tag being returned from jsreport was not getting executed when setting div.innerHtml (via an angular element ref). This was because of the security measures in Angular. It suggests using a binding in combination with use of the DomSanitizer as outlined here https://netbasal.com/angular-2-security-the-domsanitizer-service-2202c83bd90. This still didn't work.

    I finally used this and it all worked out.

           const mydiv2 = self.rptsection.nativeElement; (rptsection is an ElementRef)
    
            // a way to get .innerHTML to have executable script tags
            const fragment = document.createRange().createContextualFragment(res.toString());
            mydiv2.appendChild(fragment);
    

    Thank you for the support. It is much appreciated.


Log in to reply
 

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