microsoft/powerbi-client-react

how to detect data changes in Calendar Slicer

alan9518 opened this issue · 2 comments

Is there a way to get the selected dates from a calendar slicer control on change ?

I tried to use dataSelected, but the event doesn't trigger like with the other slicers, right now the only way i'm able to get the dates and sync with react state is in the rendered event get slicer context of the calendar visual which can take a while and then i have to do all the other business operations.

so is there a better way to get the date values without having to access the slicer context api every render ?

or a way to listen the rendered event only for that specific slicer? visualRenderedEvents: true enables the visualRendered event for all visuals but I just need it on one

image

There is no event Handler that listens to the rendered event for a specific visual.
However, as a workaround, we can use the visualRenderedEvents API along with getVisual() and getSlicerState() APIs to listen the rendered event only for a specific visual. Please go through the code snippet provided below:

useEffect(() => {
	if (!report) {
			setDisplayMessageAndConsole('Report not available');
			return;
		}

	report.on('loaded', async function(event) {
		// Report is loaded; now get the list of pages
		const reportPages = await report.getPages();

		// Register an event handler for the "Visual Rendered" event
		report.on('visualRendered', async function(visual) {
		
			if ((visual.detail as { visual: { type: string; getSlicerState: () => any[]; }; })) {
				try {
					// Get the list of pages in the report
					const pages = await report.getPages();
					// Find the active page
					let activePage = pages.find(page => page.isActive);
					if (!activePage) {
						console.error('No active page found.');
						return;
					}

					// Get the visuals on the active page
					const visuals = await activePage.getVisuals();
					// Find the slicer visual by name
					for (let i = 0; i < visuals.length; i++) {
						if (visuals[i].type === 'slicer' && visuals[i].name === 'VisualName') {
							const slicerVisual = visuals[i];
							// Get the selected dates from the slicer state
							const slicerState = await slicerVisual.getSlicerState();
							console.log('Slicer state:', slicerState);
						}
					}
				} catch (error) {
					console.log(error);
				}
			}
		});
	});
}, [report]);

There is no event Handler that listens to the rendered event for a specific visual. However, as a workaround, we can use the visualRenderedEvents API along with getVisual() and getSlicerState() APIs to listen the rendered event only for a specific visual. Please go through the code snippet provided below:

useEffect(() => {
	if (!report) {
			setDisplayMessageAndConsole('Report not available');
			return;
		}

	report.on('loaded', async function(event) {
		// Report is loaded; now get the list of pages
		const reportPages = await report.getPages();

		// Register an event handler for the "Visual Rendered" event
		report.on('visualRendered', async function(visual) {
		
			if ((visual.detail as { visual: { type: string; getSlicerState: () => any[]; }; })) {
				try {
					// Get the list of pages in the report
					const pages = await report.getPages();
					// Find the active page
					let activePage = pages.find(page => page.isActive);
					if (!activePage) {
						console.error('No active page found.');
						return;
					}

					// Get the visuals on the active page
					const visuals = await activePage.getVisuals();
					// Find the slicer visual by name
					for (let i = 0; i < visuals.length; i++) {
						if (visuals[i].type === 'slicer' && visuals[i].name === 'VisualName') {
							const slicerVisual = visuals[i];
							// Get the selected dates from the slicer state
							const slicerState = await slicerVisual.getSlicerState();
							console.log('Slicer state:', slicerState);
						}
					}
				} catch (error) {
					console.log(error);
				}
			}
		});
	});
}, [report]);

Thanks