Forum Discussion
VisualUpdate doesn't trigger in custom visual when switching from reading to edit mode
I am having the following problem:
Previously, I used dataViewMapping as TABLE and it worked fine.
But after I used dataViewMapping MATRIX instead of TABLE, it did not trigger the update function when I switched from viewmode to editmode, it only triggered the update function when I zoomed in/out of the viewport, or dragged data into visualization, and when I saved the data, saved it to persist, it did not trigger the update function.
6 Replies
- v-veshwara-msftCommunity Support
Hi ViDuong ,
Thanks for posting in Microsoft Fabric Community.
When a custom visual uses matrix dataViewMapping, switching between Reading and Edit mode may not always trigger an update, since the host might not rebuild the dataView during that action unless something in the data or layout has changed.Others have observed similar behaviour, so this might be how the platform currently handles mode transitions. Because of this, the update function may only run after actions such as resizing the visual or modifying fields.
Similar cases and related discussions were discussed here:
Visual.update() not triggered when switching from ... - Microsoft Fabric CommunityRe: VisualUpdate doesn't fire in custom visual whe... - Microsoft Fabric Community
If you feel this behaviour might not be expected, you can raise it through the Power BI Issues page for further review:
Issues - Microsoft Fabric CommunityHope this helps. Please reach out for further assistance.
Thank you.
- ViDuongFrequent Visitor
v-veshwara-msft thank you, I will try workaround
- v-veshwara-msftCommunity Support
Hi ViDuong ,
Thanks for the update.
Just to add one more detail that came up in this related discussion: Re: Visual.update() not triggered when switching f... - Microsoft Fabric Community its noted that this behaviour might only appear when the report is viewed in Actual Size mode. In other view modes, switching between Reading and Edit may trigger a resize event, which then causes the visual to receive an update with the mode flag included.
You may want to check whether the mode works differently when the report is not in Actual Size, as this might help validate the workaround you are testing.
Feel free to share your observations once you try it.
Thank you.
- Ahmed-ElfeelSuper User
Hi ViDuong,
When switching between reading mode and edit mode Power BI doesn't always trigger the update() method for matrix based visuals this happens because:
TABLE mapping creates a new dataView when mode changes
- MATRIX mapping often reuses the same dataView object
- Power BI optimizes by not calling update() if it thinks the data hasnt changed
First Approach:Force Update Using View Mode Change Events
- Add view mode change detection in your visual:
export class YourVisual implements IVisual { private host: IVisualHost; private currentViewMode: ViewMode; constructor(options: VisualConstructorOptions) { this.host = options.host; // Listen for view mode changes this.host.viewModeChanged.subscribe((viewMode: ViewMode) => { this.currentViewMode = viewMode; // Force a re-render when view mode changes this.handleViewModeChange(); }); } public update(options: VisualUpdateOptions) { this.currentViewMode = options.viewMode; // ... your existing update logic } private handleViewModeChange() { // Manually trigger UI updates for edit mode if (this.currentViewMode === ViewMode.Edit) { this.renderEditModeUI(); } else { this.renderReadModeUI(); } } }Second Approach:Use EnumerateObjects to Force Data Refresh
- Modify your capabilities to include objects enumeration:
{ "objects": { "general": { "properties": { "viewModeToggle": { "type": { "bool": true } } } } } }- Then in your update method:
public update(options: VisualUpdateOptions) { this.countRender++; this.viewMode = options.viewMode; this.events.renderingStarted(options); // Force enumerate objects to trigger updates if (options.viewMode === ViewMode.Edit) { this.host.persistProperties({ merge: [{ objectName: "general", properties: { viewModeToggle: this.viewMode === ViewMode.Edit }, selector: null }] }); } const dataView = options.dataViews?.[0]; // ... rest of your code }Third Approach:Check for Mode Specific Changes in Update
- Enhance your update method to detect mode changes:
public update(options: VisualUpdateOptions) { this.countRender++; // Check if view mode actually changed const viewModeChanged = this.viewMode !== options.viewMode; this.viewMode = options.viewMode; this.events.renderingStarted(options); const dataView = options.dataViews?.[0]; if (!dataView?.matrix) { this.dataOriginal = undefined; if (this.countRender > 3) this.clearNodePositions(); this.countRender = 0; this.renderUI(); return; } this.formattingSettings = this.formattingSettingsService.populateFormattingSettingsModel( VisualSettingsModel, dataView ); // Always render on mode change, even if data appears unchanged if (viewModeChanged) { this.renderUI(); return; } // ... your existing data processing logic }Bonus Approach:Use Update Types
- Leverage the type property in VisualUpdateOptions:
public update(options: VisualUpdateOptions) { // Check the update type if (options.type === VisualUpdateType.ViewModeChange) { // Force complete re-render this.forceFullRender = true; } // ... your existing code if (this.forceFullRender || !dataView?.matrix) { this.forceFullRender = false; this.renderUI(); return; } }if this post helps, then I would appreciate a thumbs up and mark it as the solution to help the other members find it more quickly.