Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Get Fabric Certified for FREE during Fabric Data Days. Don't miss your chance! Request now

Reply
krystina627
New Member

Transferring Filters from One Report to Another and Visual is not Updating

I am attempting to POC a Angular solution that will allow me to display two separate PowerBI reports, set filters on report 1 and transfer those same filter values to report 2. So far I have the solution to the point where I can display both reports in a component depending on whether I click a button called 'Report 1' and 'Report 2'. When I set the filters on report 1 and click the 'Report 2' button the filters from report 1 are synchronize with report 2 but the visualization of report 2 is not updated. However, when I log the new filters for report 2 I can see the new fitlers on the report 2 object but the visual will not update.

 

Here's the current reports.component.hmtl: 

 

 

<h1>Reports</h1>
<div class="button-row">
  <button mat-raised-button color="primary" (click)="toggleReport1()">Report 1</button>
  <button mat-raised-button color="primary" (click)="toggleReport2()">Report 2</button>
</div>
<powerbi-report [hidden]="isShowReport1" [embedConfig]="reportConfig1" [cssClassName]="reportClass" [phasedEmbedding]="phasedEmbeddingFlag" [eventHandlers]="eventHandlersMapReport1">
</powerbi-report>
<powerbi-report id="report2-container" [hidden]="isShowReport2" [embedConfig]="reportConfig2" [cssClassName]="reportClass" [phasedEmbedding]="phasedEmbeddingFlag" [eventHandlers]="eventHandlersMapReport2">
</powerbi-report>

 

Here's the current reports.component.ts: 

 

import { Component, OnInit, ViewChild } from '@angular/core';
import { IReportEmbedConfiguration, models, service, Embed, Report } from 'powerbi-client';
import { PowerBIReportEmbedComponent } from 'powerbi-client-angular';


@Component({
  selector: 'app-reports',
  templateUrl: './reports.component.html',
  styleUrls: ['./reports.component.scss']
})
export class ReportsComponent implements OnInit {
  @ViewChild(PowerBIReportEmbedComponent) reportObj!: PowerBIReportEmbedComponent;
  isShowReport1 = true;
  isShowReport2 = true;
  
  report1Instance: Report | undefined;
  report2Instance: Report | undefined;
  showReport2Component = false;
  filters: undefined;
  
  
  ngOnInit() {
  }

  toggleReport1() {
    this.isShowReport1 = false;
    this.isShowReport2 = true; // Hide app-report2 component
  }

  toggleReport2() {
    this.isShowReport1 = true;
    this.isShowReport2 = false;
    this.synchronizeFilters()
  }

  

  reportConfig1: IReportEmbedConfiguration = {
    type: 'report',
    embedUrl: this.report1EmbedUrl,
    tokenType: models.TokenType.Embed,
    accessToken: this.embed_token,
    settings: {
      panes: {
        filters: {
          expanded: true,
          visible: true
        }
      },
      background: models.BackgroundType.Transparent,
    }
  };

 

  reportConfig2: IReportEmbedConfiguration = {
    type: 'report',
    embedUrl: this.report2EmbedUrl,
    tokenType: models.TokenType.Embed,
    accessToken: this.embed_token,
    settings: {
      panes: {
        filters: {
          expanded: true,
          visible: true
        }
      },
      background: models.BackgroundType.Transparent,
    }
  };

  reportClass = 'reportContainer';

  phasedEmbeddingFlag = false;

  eventHandlersMapReport1 = new Map([
    ['loaded', () => {
      const report = this.reportObj.getReport();
      this.report1Instance = report;
      report.setComponentTitle('Embedded report 1');
      console.log('Report 1 has loaded');
    },
    ],
    ['rendered', () => console.log('Report 1 has rendered')],
    ['error', (event?: service.ICustomEvent<any>) => {
      if (event) {
        console.error(event.detail);
      }
    },
    ],
    ['visualClicked', () => console.log('visual clicked')],
    ['pageChanged', (event) => console.log(event)],
  ]) as Map<string, (event?: service.ICustomEvent<any>, embeddedEntity?: Embed) => void | null>;

  eventHandlersMapReport2 = new Map([
    ['loaded', () => {
      const report = this.reportObj.getReport();
      this.report2Instance = report;
      report.setComponentTitle('Embedded report 2');
      console.log('Report 2 has loaded');
    },
    ],
    ['rendered', () => console.log('Report 2 has rendered')],
    ['error', (event?: service.ICustomEvent<any>) => {
      if (event) {
        console.error(event.detail);
      }
    },
    ],
    ['visualClicked', () => console.log('visual clicked')],
    ['pageChanged', (event) => console.log(event)],
  ]) as Map<string, (event?: service.ICustomEvent<any>, embeddedEntity?: Embed) => void | null>;

  async getFiltersFromReport(reportInstance: Report): Promise<models.IFilter[]> {
    const filters = await reportInstance.getFilters();
    
    return filters;
  }

  async applyFiltersToReport(reportInstance: Report, filters: models.IFilter[]) {
    try {
      await reportInstance.updateFilters(models.FiltersOperations.ReplaceAll, filters);
      console.log("All the report filters were replaced.");
    } catch (error) {
      console.error('Error applying filters and refreshing report:', error);
    }
  }

  async synchronizeFilters() {
    if (this.report1Instance && this.report2Instance) {
      try {
        const filters = await this.getFiltersFromReport(this.report1Instance);
        console.log(filters);

        await this.applyFiltersToReport(this.report2Instance, filters);
        console.log('Filters applied to Report 2.');

        const filters2 = await this.getFiltersFromReport(this.report2Instance);
        console.log(filters2);

        console.log('Filters synchronized between reports.');
      } catch (error) {
        console.error('Error synchronizing filters:', error);
      }
    }
  }
}

 

 

 

1 ACCEPTED SOLUTION
krystina627
New Member

Resolved: Resolution was ensuring the correct report instance was being used. 

The way I was getting the report instance was not be differentiating between the two reports, which lead to an overlap. This was because I was using this.reportObj.getReport() for both reports. Instead, each powerbi-report should have its own ViewChild reference.

Modified the component with:

@ViewChild('report1') report1Obj: PowerBIReportEmbedComponent | undefined;
@ViewChild('report2') report2Obj: PowerBIReportEmbedComponent | undefined;

 

 

 And then in the HTML: 

 

<powerbi-report #report1 [hidden]="isShowReport1" [embedConfig]="reportConfig1" ...></powerbi-report>
<powerbi-report #report2 [hidden]="isShowReport2" [embedConfig]="reportConfig2" ...></powerbi-report>

 

Finally, in the event handlers: 

['loaded', () => {
   const report = this.report1Obj?.getReport();
   if (report) {
      this.report1Instance = report;
      report.setComponentTitle('Embedded report 1');
      console.log('Report 1 has loaded');
   }
}],
...
['loaded', () => {
   const report = this.report2Obj?.getReport();
   if (report) {
      this.report2Instance = report;
      report.setComponentTitle('Embedded report 2');
      console.log('Report 2 has loaded');
   }
}],

 

 

View solution in original post

1 REPLY 1
krystina627
New Member

Resolved: Resolution was ensuring the correct report instance was being used. 

The way I was getting the report instance was not be differentiating between the two reports, which lead to an overlap. This was because I was using this.reportObj.getReport() for both reports. Instead, each powerbi-report should have its own ViewChild reference.

Modified the component with:

@ViewChild('report1') report1Obj: PowerBIReportEmbedComponent | undefined;
@ViewChild('report2') report2Obj: PowerBIReportEmbedComponent | undefined;

 

 

 And then in the HTML: 

 

<powerbi-report #report1 [hidden]="isShowReport1" [embedConfig]="reportConfig1" ...></powerbi-report>
<powerbi-report #report2 [hidden]="isShowReport2" [embedConfig]="reportConfig2" ...></powerbi-report>

 

Finally, in the event handlers: 

['loaded', () => {
   const report = this.report1Obj?.getReport();
   if (report) {
      this.report1Instance = report;
      report.setComponentTitle('Embedded report 1');
      console.log('Report 1 has loaded');
   }
}],
...
['loaded', () => {
   const report = this.report2Obj?.getReport();
   if (report) {
      this.report2Instance = report;
      report.setComponentTitle('Embedded report 2');
      console.log('Report 2 has loaded');
   }
}],

 

 

Helpful resources

Announcements
FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.