Javascript Error
mhouttemane opened this issue · 10 comments
Hi !
I'm trying to embed power Bi reports in my salesforce organization through LWC and Aura component (same problems with the 2).
I follow this explanations : https://github.com/PowerBiDevCamp/SalesforceAppOwnsDataEmbedding
However, I get an error on each time, I load the page.User-added imageIn javascript, screenshot of the message is attached.
aura_proddebug.js:28891 Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'Window': # could not be cloned.
at Object.postMessage (https://myOrg.lightning.force.com/auraFW/javascript/7FPkrq_-upw5gdD4giTZpg/aura_proddebug.js:28891:46)
at WindowPostMessageProxy.sendResponse (https://myOrg.lightning.force.com/resource/1642763618000/powerbijs:6067:23)
at eval (https://myOrg.lightning.force.com/resource/1642763618000/powerbijs:6135:32)
It seems that something went wrong between aura framework and powerbi javascript.
Here is the code :
powerBiReport.html :
<template> <lightning-card title="Embedded Power BI Report (LWC)" icon-name="utility:graph"> <div class="slds-m-around_medium"> <template if:true={report.data}> <template if:true={report.data.error}> <div>{report.data.error}</div> </template> </template> <template if:true={report.data}> <template if:true={report.data.embedUrl}> <div lwc:dom="manual" data-id="embed-container" style="height: 480px"> </div> </template> </template> </div> </lightning-card> </template>
powerBiReport.js
`import { LightningElement, api, wire, track } from 'lwc';
import getEmbeddingDataForReport from '@salesforce/apex/PowerBiEmbedManager.getEmbeddingDataForReport';
import powerbijs from '@salesforce/resourceUrl/powerbijs';
import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
export default class PowerBiReport extends LightningElement {
@api WorkspaceId ='';
@api ReportId ='';
@track reportBI;
count = 0;
@wire(getEmbeddingDataForReport,{
WorkspaceId: "$WorkspaceId",
ReportId: "$ReportId"
}) report;
renderedCallback() {
console.log('renderedCallback exectuting');
Promise.all([ loadScript(this, powerbijs ) ]).then(() => {
console.log('renderedCallback 2');
console.log("this.report", this.report);
if(this.report.data){
if(this.report.data.embedUrl && this.report.data.embedToken){
var reportContainer = this.template.querySelector('[data-id="embed-container"');
var reportId = this.report.data.reportId;
var embedUrl = this.report.data.embedUrl;
var token = this.report.data.embedToken;
var config = {
type: 'report',
id: reportId,
embedUrl: embedUrl,
accessToken: token,
tokenType: 1,
settings: {
panes: {
filters: { expanded: false, visible: true },
pageNavigation: { visible: false }
}
}
};
// Embed the report and display it within the div container.
var reportBI = powerbi.embed(reportContainer, config);
console.log(powerbi);
}
else {
console.log('no embedUrl or embedToken');
}
}
else{
console.log('no report.data yet');
}
});
}
}`
PowerBiEmbedManager.cls
`public with sharing class PowerBiEmbedManager {
public PowerBiEmbedManager() {}
public class ClientCredentialPostData {
public String client_id;
public String client_info;
public string client_secret;
public String scope;
public string grant_type;
public String getPostData(){
return 'client_id=' + this.client_id +
'&client_info=' + this.client_info +
'&client_secret=' + this.client_secret +
'&scope=' + this.scope +
'&grant_type=' + grant_type;
}
}
public class ClientCredentialResponse {
public String access_token;
public String expires_in;
public String ext_expires_in;
public String token_type;
}
public class PowerBiReport {
public String id { get; set; }
public String reportType { get; set; }
public String name { get; set; }
public String webUrl { get; set; }
public String embedUrl { get; set; }
public boolean isFromPbix { get; set; }
public boolean isOwnedByMe { get; set; }
public String datasetId { get; set; }
}
public class PowerBiEmbedToken {
public string token { get; set; }
public string tokenId { get; set; }
public DateTime expiration { get; set; }
}
public class PowerBiReportData {
@AuraEnabled
public String workspaceId { get; set; }
@AuraEnabled
public String reportId { get; set; }
@AuraEnabled
public String name { get; set; }
@AuraEnabled
public String embedUrl { get; set; }
@AuraEnabled
public String embedToken { get; set; }
@AuraEnabled
public DateTime embedTokenExpires { get; set; }
@AuraEnabled
public String error { get; set; }
}
public static String getPowerBiAccessToken() {
// get auth settings from Custom Metadata Type reconrd
Power_BI_Auth_Setting__mdt authSetting = Power_BI_Auth_Setting__mdt.getInstance('PowerBiApp');
string TenantId = authSetting.TenantId__c;
string ClientId = authSetting.ClientId__c;
string ClientSecret = authSetting.ClientSecret__c;
// construct URL for client credentials flow
String aadTokenEndpoint = 'https://login.microsoftonline.com/' + TenantId + '/oauth2/v2.0/token';
// prepare HTTP request
HttpRequest reqClientCredentialsFlow = new HttpRequest();
reqClientCredentialsFlow.setMethod('POST');
reqClientCredentialsFlow.setEndpoint(aadTokenEndpoint);
reqClientCredentialsFlow.setHeader('Content-Type', 'application/x-www-form-urlencoded');
// compose data for POST body
ClientCredentialPostData postData = new ClientCredentialPostData();
postData.client_id = ClientId;
postData.client_info = '1';
postData.client_secret = ClientSecret;
postData.scope = 'https://analysis.windows.net/powerbi/api/.default';
postData.grant_type = 'client_credentials';
String postBody = postData.getPostData();
reqClientCredentialsFlow.setBody(postBody);
// send HTTP POST to execute client credentials flow
Http http = new Http();
HttpResponse response = http.send(reqClientCredentialsFlow);
// extract and return app-only access token for service principal
String responseJson = response.getBody();
ClientCredentialResponse responseData = (ClientCredentialResponse)JSON.deserialize(responseJson, ClientCredentialResponse.class);
String access_token = responseData.access_token;
return access_token;
}
@AuraEnabled(cacheable=true)
public static PowerBiReportData getEmbeddingDataForReport(String WorkspaceId, String ReportId) {
// get access token for Authorization header
String access_token = getPowerBiAccessToken();
// Call to Power BI Service API to get report data for embedding
HttpRequest reqGetReport = new HttpRequest();
reqGetReport.setMethod('GET');
String urlGetReport = 'https://api.powerbi.com/v1.0/myorg/groups/' + WorkspaceId + '/reports/' + ReportId;
reqGetReport.setEndpoint(urlGetReport);
reqGetReport.setHeader('Authorization', 'Bearer ' + access_token);
Http http = new Http();
HttpResponse response = http.send(reqGetReport);
// check response for success
if(response.getStatusCode()!=200){
System.debug('ERROR --- Getting Report Data --- ERROR');
System.debug('Status Code: ' + response.getStatusCode());
PowerBiReportData getReportError = new PowerBiReportData();
getReportError.error = 'Get Report Error: ' + response.getStatus();
return getReportError;
}
// extract Power BI report data from JSON response
String responseJson = response.getBody();
PowerBiReport powerBiReport = (PowerBiReport)JSON.deserialize(responseJson, PowerBiReport.class);
// send report info to debug window
System.debug('id: ' + powerBiReport.id);
System.debug('reportType: ' + powerBiReport.reportType);
System.debug('name: ' + powerBiReport.name);
System.debug('webUrl: ' + powerBiReport.webUrl);
System.debug('embedUrl: ' + powerBiReport.embedUrl);
System.debug('isFromPbix: ' + powerBiReport.isFromPbix);
System.debug('isOwnedByMe: ' + powerBiReport.isOwnedByMe);
System.debug('datasetId: ' + powerBiReport.datasetId);
// Call to Power BI Service API to get embed token for report
HttpRequest reqGetEmbedToken = new HttpRequest();
reqGetEmbedToken.setMethod('POST');
String urlGetEmbedToken = 'https://api.powerbi.com/v1.0/myorg/groups/' + WorkspaceId + '/reports/' + ReportId + '/GenerateToken';
reqGetEmbedToken.setEndpoint(urlGetEmbedToken);
reqGetEmbedToken.setHeader('Authorization', 'Bearer ' + access_token);
reqGetEmbedToken.setHeader('Content-Type', 'application/json');
//reqGetEmbedToken.setBody('{"accessLevel": "View", "datasetId": "' + powerBiReport.datasetId + '"}');
reqGetEmbedToken.setBody('{"accessLevel": "View", "identities" : [{"username": "oneuser@myorg.fr", "roles":["All"], "datasets": ["cec11a11-1c1f-111b-b11b-11aac11111bd"]}]}');
System.debug('Request body : ' + reqGetEmbedToken.getBody());
HttpResponse responseEmbedToken = http.send(reqGetEmbedToken);
// check response for success
if(responseEmbedToken.getStatusCode()!=200){
System.debug('ERROR --- Getting Embed Token --- ERROR');
System.debug('Status Code: ' + responseEmbedToken.getStatusCode());
PowerBiReportData getEmbedTokenError = new PowerBiReportData();
getEmbedTokenError.error = 'Get Embed Token Error: ' + responseEmbedToken.getStatus();
System.debug('Response body : ' + responseEmbedToken.getBody());
return getEmbedTokenError;
}
// extract Power BI embed token and expiration
PowerBiEmbedToken embedToken = (PowerBiEmbedToken)JSON.deserialize(responseEmbedToken.getBody(), PowerBiEmbedToken.class);
// send report info to debug window
System.debug('EmbedToken: ' + embedToken.token);
System.debug('EmbedToken ID: ' + embedToken.tokenId);
System.debug('expiration: ' + embedToken.expiration);
// create custom remote-able object to return to caller in browser
PowerBiReportData powerBiReportData = new PowerBiReportData();
powerBiReportData.workspaceId = WorkspaceId;
powerBiReportData.reportId = ReportId;
powerBiReportData.name = powerBiReport.name;
powerBiReportData.embedUrl = powerBiReport.embedUrl;
powerBiReportData.embedToken = embedToken.token;
powerBiReportData.embedTokenExpires = embedToken.expiration;
return powerBiReportData;
}
}`
From the example, I just add two lines in PowerBiEmbedManager :
reqGetEmbedToken.setHeader('Content-Type', 'application/json');
reqGetEmbedToken.setBody('{"accessLevel": "View", "identities" : [{"username": "oneuser@myorg.fr", "roles":["All"], "datasets": ["cec11a11-1c1f-111b-b11b-11aac11111bd"]}]}');
Can you please help me or give me some advices ?
Thank you
Maxime
Hi!
I am having the exact same problem. The exception is thrown 5 times on every page load.
aura_prod.js:88 Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'Window': # could not be cloned.
at Object.postMessage (https://static.lightning.force.com/cs66/auraFW/javascript/7FPkrq_-upw5gdD4giTZpg/aura_prod.js:88:92459)
at WindowPostMessageProxy.sendResponse (https://campbellsfoodservice--boylanm.lightning.force.com/resource/1637179820000/powerbijs:6070:23)
at eval (https://campbellsfoodservice--boylanm.lightning.force.com/resource/1637179820000/powerbijs:6138:32)
Im also having the same issue with LWC, Aura seems to work ok.
Im also having the same issue with LWC, Aura seems to work ok.
I've also the same issue in Aura...
For me LWC and Aura don't work.
Does anyone have any new information on this issue?
Has there been any news on this? Has anyone found a solution?
No In the end I went with Aura as the error didn't seem to occur.
No In the end I went with Aura as the error didn't seem to occur.
Hello,
Can you please show me how you did it ?
I have the same error with Aura as well.
Thank you !
Hello,
found some information online that might have helped. It seems it is failing in the static resource file powerbijs.js at line 6067. I have added a workaround code at this property assignment:
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, ' '));
}
// Fix starts here:
var windowMessage = '' + message;
// Replace below line:
// targetWindow.postMessage(message, "*");
targetWindow.postMessage(windowMessage, "*");
};
did a quick test, and did not see any side effects, so I am assuming it works. Not a JS expert, so if there are any JS experts out there that can explain why this fixed the issue, that would be great.
Thanks!
Hello,
found some information online that might have helped. It seems it is failing in the static resource file powerbijs.js at line 6067. I have added a workaround code at this property assignment:
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, ' ')); } // Fix starts here: var windowMessage = '' + message; // Replace below line: // targetWindow.postMessage(message, "*"); targetWindow.postMessage(windowMessage, "*"); };
did a quick test, and did not see any side effects, so I am assuming it works. Not a JS expert, so if there are any JS experts out there that can explain why this fixed the issue, that would be great.
Thanks!
Hello !
I can confirm this is working.
Thank you !
This appears to fix the issue for me too. I was getting 5 popup error messages as described by other users