3

I have recently been working on embedding power bi into a salesforce LWC, as outlined here: https://github.com/PowerBiDevCamp/SalesforceAppOwnsDataEmbedding. Pretty cool stuff, but the particular use case may be beside the point. I am having some sort of rendering issues with the lightning web component. Here it is:

import { LightningElement, api, wire } from 'lwc';
import getEmbeddingDataForReport from '@salesforce/apex/PowerBiEmbedManager.getEmbeddingDataForReport';
import powerbijs from '@salesforce/resourceUrl/powerbijs';
import { loadScript } from 'lightning/platformResourceLoader';

export default class PowerBiReport extends LightningElement {
  @api WorkspaceId = '';
  @api ReportId = '';
  @api recordId;
   
  @wire(getEmbeddingDataForReport,{
    WorkspaceId: "$WorkspaceId",
    ReportId: "$ReportId"
  }) report;
    renderedCallback() {
      Promise.all([ loadScript(this, powerbijs ) ]).then(() => {
        if(this.report.data){
              if(this.report.data.embedUrl && this.report.data.embedToken){
                const reportContainer = this.template.querySelector('[data-id="embed-container"');
                const reportId = this.report.data.reportId;

                const embedUrl = this.report.data.embedUrl;
                const token = this.report.data.embedToken;

                var visualConfig = {
                  accessToken: token,
                  embedUrl: embedUrl,
                  id: reportId,
                  pageName: 'ReportSection',
                  tokenType: 1,
                  type: 'visual',
                  visualName: '1837fab00804802016c6',
                  settings: {
                    panes: {
                      filters: { expanded: false, visible: true },
                      pageNavigation: { visible: false}
                    }
                  }
                }
                // Embed the report and display it within the div container.
                var report = powerbi.embed(reportContainer, visualConfig); 
              }
              else {
                console.log('no embedUrl or embedToken');
              }
                
              }
              else{
                  console.log('no report.data yet');
              }
        });
    }
}

Now this works fine and as intended. The getEmbeddingDataForReport returns all the necessary data (embed url, token, etc...), and I have the chart embedding and showing up (mostly) properly. I have the lightning web component on a lightning record page. But here's the problem. Occasionally when the page loads, I get an error message: enter image description here

After occasionally getting this error pop-up, I did some digging and noticed that I ALWAYS get it if I click on 'Edit Page' to pull up the lightning page where the LWC is embedded. When opening the console, I see this error message duplicated about 4 or 5 times: "Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'Window': # could not be cloned." enter image description here

After logging at some random places, I noticed that I do not get this error if I comment out the line where powerbi.embed uses the configurations and selected html id to embed the actual report. So, there is either something wrong with this line:

var report = powerbi.embed(reportContainer, visualConfig);

or this line:

const reportContainer = this.template.querySelector('[data-id="embed-container"');

I am pretty stumped on this. I don't have the slightest idea why this could be happening. I read a couple things online that indicated this error often relates to embedding a LWC in a context that doesn't support LWCs and that the solution would be to wrap the LWC in an Aura component; however, I don't believe that applies here because the LWC is embedded in a lightning record page, which clearly supports LWCs. So, somethings is going on under the hood here relating to one of those two lines I pointed out...any ideas what is happening here? Please help!!

3
  • 1
    How many times is the renderedCallback function being called?
    – Nick C
    Commented May 4, 2023 at 4:56
  • 1
    Nick is correct, you need a boolean lock to prevent multiple loads. Check out how we did it here with another lib: github.com/trailheadapps/lwc-recipes/blob/main/force-app/main/…
    – POZ
    Commented May 4, 2023 at 8:39
  • I tried this, but this does not appear to be the problem. renderedCallback is only being called twice, once when the LWC initially renders and once when it gets the power bi data. This is expected. There is some sort of issue with the .embed() method. Commented May 10, 2023 at 19:28

1 Answer 1

1

You're likely getting this error because there is an issue with the powerbi.js that you uploaded as a Static Resource. I had this issue on v2.21.1 of powerbi.js.

This issue can be tracked down to the function assigned to WindowPostMessageProxy.prototype.sendResponse. I deep cloned message as per this thread and it seemed to do the trick. This answer explains the reasoning behind the error very well.

The message parameter being passed to this function can also occasionally be null, so I added a null check and for message and all was good to go.

After my fix, the function looks something like this:

WindowPostMessageProxy.prototype.sendResponse = function (targetWindow, message, trackingProperties) {
    this.addTrackingProperties(message, trackingProperties);
    if (this.logMessages) {
        console.log(this.name + " Sending response:");
        console.log(JSON.stringify(message, null, '  '));
    }
    if (!message) {
        return;
    }
    message = JSON.parse(JSON.stringify(message))
    targetWindow.postMessage(message, "*");
};

As an aside, I believe the powerbi.js is now at v2.22.2 based on the link in the PowerBiDevCamp repo, so that might also fix your issue. If it does not, I can vouch for the stability of v2.21.1 after applying the above fix.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .