microsoft / powerbi-client-angular

Power BI Angular component. This library lets you embed Power BI report, dashboard, dashboard tile, report visual, or Q&A in your Angular application.
Other
131 stars 63 forks source link

Sometimes (and only sometimes) the report doesn't render after being loaded. #68

Open GilmarCoop opened 1 month ago

GilmarCoop commented 1 month ago

I've been facing a problem recently where the report loads just fine, but doesn't render at all — and it doesn't show any errors.

Here's my code:

export class DashboardComponent implements OnInit {
    embeddedConfig: IReportEmbedConfiguration =  { type: 'report' };
    eventHandlersMap = new Map([
        ['loaded', () => console.log('PBI: Report loaded')],
        ['rendered', () => console.log('PBI: Report rendered')],
        ['error', function (event) { console.log(`PBI: ${event.detail}`) }]
    ]);

    @ViewChild(PowerBIReportEmbedComponent) reportObj!: PowerBIReportEmbedComponent;

    constructor() { }

    ngOnInit() {
        this.getReportConfig();
    }

    getReportConfig() {
        this.embeddedConfig = {
            type: 'report',
            embedUrl: myURL,
            tokenType: models.TokenType.Embed,
            accessToken: myToken,
            settings: {
                layoutType: models.LayoutType.Custom,
                customLayout: {
                    displayOption: models.DisplayOption.FitToWidth,
                }
            },
            hostname: "https://app.powerbi.com"
        }
    }
}

And here's the HTML:

<powerbi-report [embedConfig]="embeddedConfig" cssClassName="report-container" phasedEmbedding="false"
    [eventHandlers]="eventHandlersMap">
</powerbi-report>
ravindUwU commented 3 weeks ago

FWIW, I'm on "powerbi-client": "^2.22.3", "powerbi-client-angular": "^3.0.5" and noticed a while ago that <powerbi-report> doesn't seem to handle [embedConfig] changes gracefully 🤔 (IIRC; it either didn't load at all or threw a bunch of errors; but I'm unable to repro/test this at the moment). Unsure if this is related to the issue that you're facing.

I got it working by removing the <powerbi-report> entirely from the DOM and adding it with the new [embedConfig] after a slight delay whenever the config changed 💁.

Something like,

readonly config = new BehaviorSubject<Config | null>(null);

readonly renderedConfig = this.config.pipe(
    switchMap((config) =>
        config !== null
            ? concat(
                    // Un-render
                    of(null),
                    // Render a little while later...
                    of(config).pipe(delay(1_000))
                )
            : of(null)
    )
);
<ng-container *ngIf="{ config: renderedConfig | async } as ctx">
    <powerbi-report
        *ngIf="ctx.config !== null"
        [embedConfig]="ctx.config"
    >
    </powerbi-report>
</ng-container>
v-MadhavC commented 2 weeks ago

Hi @GilmarCoop, we've tested the code you provided and didn't encounter any issues. Could you provide more details about what happens when the report fails to load?

GilmarCoop commented 2 weeks ago

Hey there, @v-MadhavC!

Well, there's not much to say, as nothing actually happens after the report is loaded (no event is triggered and no error occurs). However, I've noticed that removing the iframe's source and setting it back forces the report to re-render. I used this technique to temporarily fix the issue, as users really needed to see the report.

If it helps, these two logs are displayed in the console once I navigate to the component:

image

v-MadhavC commented 1 week ago

There is some discrepancy in the error message. We will work on updating this to provide a more accurate message.

Currently, the log message Power BI SDK iframe is loaded but powerbi.embed is not called yet appears when the embedConfig does not contain an access token at the time the <powerbi-report> selector is called.

To resolve this, ensure that the access token is defined when the component is rendered. Please verify that the logic to generate the access token properly fetches it and assigns it to reportConfig before the HTML component is rendered.