Einstein Analytics: Demystifying Bindings – Part 1
Creating dashboards in Einstein Analytics is easy and it becomes yet easier with every release. But sometimes you want your users to have even more dynamic controls in the dashboards and this is when you start introducing more advanced functionality like bindings. If you are new to Einstein Analytics or even if you have been working with Einstein Analytics for a while understanding the binding syntax can be hard. So I thought it was time to demystify the hardest part of it: the syntax.
A binding in Einstein Analytics is not just a binding. There are different syntax variations of bindings and it would be hard to cover every variation in one blog. In this particular post, I will be looking to give an introduction to the most commonly used binding; result and selection binding for compact form. Remember compact format is the default way a query is written through the UI, for advanced queries you can switch to SAQL.
Where to Use Bindings
I wrote that bindings can be used to give the users more flexibility in the dashboard. But what does this mean? Well, a dashboard consists of widgets (charts, number, text etc.) and steps, both have different parameters that can be defined in the UI. These same parameters can be overwritten with a binding to pass in a dynamic parameter. Hence you can use bindings to dynamically parametrize part of a query (the grouping, measure, limit, filter and order) or to dynamically change the color or label in a widget, which you can not do in the UI. The use cases are endless. If you want to see different bindings in action, I recommend installing the templated app “Learning Adventure” and check out the dynamic dashboard section. Note that from Winter 19 this it is no longer required to install the app from AppExchange, it is now available as a templated app by default.
Binding Functions
There are two types of binding functions; ‘result’ and ‘selection’ binding. And when you start writing your binding you have to determine if you want the binding to happen with or without user interference. When viewing a dashboard all steps are executed and any ‘result’ bindings will also automatically trigger to insert the desired values. In contrast ‘selection’ binding will need the user to click on the source step of the binding for the binding to execute and update the values. It all, of course, comes down to the use case, but an easy way to determine which one to use is to ask this question:
“Should my user click on anything on the dashboard in order to trigger the binding?”.
If the answer is ‘yes’ then you are looking to do a ‘selection’ binding. If the answer is ‘no’ then you need to use a ‘result’ binding. Generally, when you are using ‘static’ steps you are always working with ‘selection’ bindings – unless you can use the ‘connect data sources’ functionality – and when you are working with “hidden” steps you want to use ‘result’ bindings. You can check out my blog on static steps to see some examples for ‘selection’ bindings or check out the documentation. For an example of a ‘result’ binding check out my blog on how to make a gauge chart dynamic or have a look at the documentation.
Binding Syntax
Okay, let’s get down to the syntax of a binding. Instead of an actual binding, I have tried to include the different component of a binding.
"{{Data_Selection_Function(step_name.Binding_Function, Details_From_Reference_Step).Data_Serialization_Function()}}"
If we convert this into an actual example it could look something like below – in this particular case, it’s a selection binding.
"{{column(Step_1.selection, ["value"]).asObject()}}"
Binding Components
Let’s have a closer look at the different components of a binding as mentioned in the above syntax.
Data Selection Function: this function determines what data is being selected from a step or table. It can either be data from a cell, column or row.
Step Name: this is the step API name (not the label) where the binding should select the data from.
Binding Function: this is the type of binding that should be used; result or selection.
Details from Reference Step: this is related to the data selection function. It defines that field or column in the table to grab as well as what row should be used. The latter is only relevant for cell() and row() functions.
Data Serialization Function: this defines how the data is formatted for example a string with double quotes, an array of strings, an array of array, etc., so it is fit to be used in the binding.
Please refer to the documentation if you want more details.
Getting Started
When I am writing a binding, I ask a few questions in the process to determine how my binding should look. But before I start writing I, of course, have to go to the dashboard JSON (command+E or control+E)and find the source step and fields that I’m using as parameters in my binding.
When it comes to the actual binding the first step, however, is to write the basics; quotes and curly brackets. And please note that a binding is case sensitive. Generally, everything is in lower case but be aware of API names and data serialization – here upper case often appear.
"{{}}"
The second step is I ask the question we already covered: “Should my user click on anything on the dashboard in order to trigger the binding?”. This will determine whether I should use a ‘selection’ or ‘result’ binding.
"{{.selection}}"
The third step is to define which step do we need to take the selection (or result) from. Hence you need to know the step API name – not the label. You can always find this in the UI if you are unsure of the name.
"{{Step_1.selection}}"
The fourth step is to define data selection function. The question I tend to ask is “looking at the step we are referencing, do I want to have information from a cell or column?”. Technically you could also get information from a row, but the most typical use cases use the functions cell() or column().
"{{column(Step_1.selection)}}"
The fifth step is where I define the data serialization function. For this, I ask the question “what result of data from my referencing step am I expecting?”. By this I mean is it one value or an array of information? If you look at the data selection function it tends to be that if you use column() then you need to use .asObject() and if you use cell() then you should use .asString() as your data serialization function. Note this heavily dependent on where you are putting your binding, for instance, the “group” or “filter” section of a query requires arrays hence you should use .asObject() and a color value or label of a line in a widget is typically one cell value, which is why you would use asString().
"{{column(Step_1.selection).asObject()}}"
The sixth step is to complete the data selection function. We have defined if we want to use a cell() or a column() and which step to use, but we have not defined what information to take. So next we need to define the field we want to grab. Since we have defined that we are expecting an array of information (we used column), as a result, we need to wrap this in brackets. If we were just expecting one value (ex. cell) and using .asString() then there is no need to use brackets. Also, note that we need to escape the string by using “”.
"{{column(Step_1.selection, ["value"]).asObject()}}"
Now in this example, we are using column(), so we only have to define the column we want to use, but if we were using a cell() we need to also define which row to take the cell from. Also, in this case, we would not be looking at an array of information so we would be using .asString() instead of .asObject(). In that case, the binding would have looked like below.
"{{cell(Step_1.selection, 0, "value").asString()}}"
Following these steps completes the basic binding.
That Thing Called columnMap
If you are binding parts of a query like measures and groupings then there is one more step to remember. In Spring 18 a new parameter called ‘columnMap’ was introduced to steps and widgets. You need to make sure to set this parameter to null or make another binding, a walkthrough of how to bind to columnMap can be found here, or how to set it to null here.
Checking out the result
If you have followed all the steps and your binding is using the correct syntax then you should have a more dynamic dashboard.
A tip I would like to pass on as well is before you switch from the dashboard JSON to view your dashboard do make sure you copy the JSON for the whole dashboard. Sometimes if the syntax is wrong or you deleted something you didn’t mean to you may be forced to do a refresh, which makes you lose all your changes. If you have the JSON copied you can always paste it back in.
From teaching others how to do binding it is my experience that most errors in bindings happen because of incorrect references. By this, I mean that references are case sensitive, so if you are using ‘accountid.industry’ or ‘account.id.industry’ but it’s actually ‘AccountId.Industry’ then your binding will not work.
Finally, the best way to visualize or understand how the binding is being rendered, always view the ‘Query Details’ by clicking on the drop down of the widget then ‘View Details’ and then ‘View more details’ icon to see how the bindings are rendering and the values being passed. It’s a good way to debug if your syntax is correct but you are not getting the expected result.
Continue on and read more about bindings:
- filter bindings in SAQL
- grouping and measure bindings in SAQL
- date bindings
- nested bindings
- bindings in compare tables
- bindings on grain steps
- data manipulation functions.
All the bindings I have used in the above-mentioned blogs can be installed in any developer org by following this guide. If you are struggling to choose the right data selection or data serialization, then check out this blog.
Thanks for this. There just isn’t enough down-to-earth material on this stuff, and your careful effort in explaining it is very appreciated. I like that you explained the context first and then went through syntax step-by-step. Bindings are confusing and I will add this to the so few resources freely available to attempt again to make sense of them.
Thanks for the feedback. It means a lot to hear that it makes sense the way I put it together. I thought there was a gap for a simple explanation and know how it is to start out not knowing what is is.
Hello Rikke. Thank you for creating this helpful information. I am struggling to create a toggle for chart and table view. Do you think it is possible?
Thank you for this great tutorial. Great explanation and breakdown of the binding functions. It would be great to see a more comprehensive breakdown of the uses for the other data serialization functions such as asGrouping, asOrder, etc. The developer guide notes they are for SAQL functions but doesn’t clearly denote examples and why.
Thanks for your suggestion. That’s actually why this post is called part 1 🙂 I am planning to write at least one more going through SAQL bindings
Nice work, Rikke! Please note that we include lots of binding use cases in the Einstein Analytics Learning Adventure app. We provide a link to it in this help topic:
https://developer.salesforce.com/docs/atlas.en-us.220.0.bi_dev_guide_bindings.meta/bi_dev_guide_bindings/bi_dashboard_bindings_wave_designer_use_cases.htm?search_text=Learning%20Adventure%20App
To deploy this Einstein Analytics app, go to Create > Template App in Analytics Studio, then search for “Learning Adventure.”
Hi, Thanks for your clear definition of how to use the bindings? Can you please confirm when we use bindings in Filter then we should use Cell () and when we use in Groups it should be Column(). Please confirm
Well, you have to think about what you want from the source. If you want to be able to select several things and make sure all the selections are passed you have to use a column. If you only use cell it will just grab one value.
Great Thanks, in case of multi-select value i should certainly use Column() right?
Yes
Thanks Rikkie, much appreciated
“{{column(Step_1.selection, [\”value\”]).asObject()}}”
Didn’t work for me
I used
“{{coalesce(column(Static_Limit_1.selection, [\”Display\”]), \”\”).asObject()}}”
That’s because you don’t have a column called value. Though display is typically not used as it’s often different that the api name of the column you want to grab.
Oh thank you so much for this amazing explanation
I was looking for the right explanation and got it here
I was stuck with Tableau CRM Super badge in Trailhead and was looking around on google for some information as many people. posted there solutions but It was going all over my head but yes finally I am able to relate now 🙂
Dear
thanks for this it is very helpful for me
I have some question about the binding function as below
is it possible that the source argument cloud be the table source?
cell(source, rowIndex, columnName)
I found that there are many samples that the source is setted by toggle or tab source
looking forward your reply
best regards
Dear
thanks for this it is very helpful for me
I have some question about the binding function as below
is it possible that the source argument cloud be the table source?
cell(source, rowIndex, columnName)
I found that there are many samples that the source is setted by toggle or tab source
looking forward your reply
best regards
Hello Rikke,
I want to ask how to use data manipulation functions . Is there any sample user case which I can refer. I have to use it in a project.
Thanks a lot Rikke for this wonderful material !!!