In trying to answer a StackOverflow question, I quickly got sidetracked into playing around with the Microsoft Power BI Javascript Embed API / Library / SDK – something that I had never used before (or Power BI at all for that matter). Here are some “oddities” that I ran into that might help others to report on:
How to reset a Slicer state via the JS Embed Library:
“Slicers” are a form of Power BI “Visuals” that can contain filters, which is to say they are embedded widgets within a report that let the user filter the data that is shown across the report page. Unlike the global filters, which can be cleared by calling embed.removeFilters()
, there is no built-in method for resetting a slicer, since slicerVisual.removeFilters()
does not necessarily reset the actual slicer state. However, you can easily reset it by calling setSlicerState and setting an “empty” state, like this:
slicerVisual.setSlicerState({filters:[]})
Fun fact – the above is basically how removeFilters()
also works – basically just an alias for setFilters([]);
How about a practical example – what if you want to reset every slicer filter when a single “reset all filters” button is pressed? You could have the following code execute:
async function resetAllSlicers() {
let report = powerbi.embeds[0];
let pages = await report.getPages();
for (let x = 0; x < pages.length; x++) {
let visuals = await pages[x].getVisuals();
for (let x = 0; x < visuals.length; x++) {
if (visuals[x].type === 'slicer') {
// Clear state, but wait before moving on to next one, since clearing a filter can have a cascade effect
try {
let cleared = await visuals[x].setSlicerState({ 'filters': [] });
}
catch (e) {
// setSlicerState or getSlicerState will fail if visual element is not initialized
// visualConfigIsNotInitialized
}
}
}
}
}
How to use “Hierarchy” filters with reports or slicers
There is a strange column type (if you can call it that) within Power BI – a “Hierarchy”. It is similar to column groups, but different in that it is more structured and, like its name would imply, is a hierarchical set of structured data/fields, that can be nested multiple layers deep. Here is what it looks like inside the built-in filter side panel:
So, how do we filter on a column/field inside a hierarchy? It doesn’t seem to be well documented, but it is pretty simple, for example:
var report = powerbi.embeds[0];
var filter = {
"$schema": "http://powerbi.com/product/schema#basic",
"target": {
"table": "Geo",
"hierarchy": "GeoRollup",
"hierarchyLevel": "Zip"
},
"operator": "In",
"values": [
"73555"
]
}
report.setFilters([filter]);
Or, it seems like you can also just filter on the nested field itself, as if it belonged directly to the table. I’m guessing this is only working for me because there is no naming conflict between a nested field and a regular field:
var report = powerbi.embeds[0];
var filter = {
"$schema": "http://powerbi.com/product/schema#basic",
"target": {
"table": "Geo",
"column": "Zip"
},
"operator": "In",
"values": [
"73555"
]
}
report.setFilters([filter]);
Some helpful resources:
- Power BI Javascript Client Repo
- Power BI JS/TS Models Repo
- Power BI Embedded Playground (has a bunch of demos, no login required)
Very good walk through. I liked the way you used the promises in your flow. By any chance, do you know what triggers the “visual config”. I am playing around with this technique and I am having the same results with a page that has been shown, but will get the visualConfigIsNotInitialized error on one that has not been shown. I really would like to set the slicer state of some pages that are further down my report before they are presented to the user.