Einstein Analytics: Demystifying Bindings – Part 8
This blog series has almost come to an end. From part 1 of this blog series I have tried to demystify the binding syntax and come with different examples of how to use data selection and data serialization, and I hope bindings have become a little more approachable than before. But there is another layer of complexity to bindings that sometimes proves helpful, I am talking about data manipulation functions.
What is data manipulation?
First of all, let me be clear, you do not always need to add a data manipulation function to your binding, this is by no means mandatory when writing a binding, which hopefully doesn’t come as a surprise if you have been following this binding series. So with that said, what is data manipulation? Well, data manipulation is something we can add to our binding to manipulate the format of the output of our binding. There are different functions we can leverage but in my own subjective and personal opinion, you will not work with them all. Personally, I rarely work data manipulation functions and when I do it’s the same ones. Regardless here are the different functions:
- coalesce
- concat
- flatten
- join
- slice
- toArray
- valueAt
In this blog series, I have chosen not to cover all of them, because it’s likely there are some of these that you will never use. However, feel free to look at the documentation should you need to manipulate the output of your binding further.
Most commonly used data manipulation
To illustrate two data manipulation functions I have created a dashboard with three steps. The use case is to make the reference line of the bar chart dynamic based on the average sum of Amount. Also, the text of the reference line should display what is selected on the map.
The first step is a map called Map_1, which is simply grouped by Billing State and has sum of Amount as the measure. See the query below.
"query": { "measures": [ [ "sum", "Amount" ] ], "groups": [ "Account.BillingState" ] }
The next step is a bar chart showing the sum of Amount by Industry. The query is sorted descending and I’ve added a reference line. You can put the value to anything you want and give the text a name that is easy to find like “Bindings Rock”. See the query of my step ‘Industry_1’.
"query": { "measures": [ [ "sum", "Amount" ] ], "groups": [ "Account.Industry" ], "order": [ [ "sum_Amount", { "ascending": false } ] ] }
Also, see the details of the reference line from the chart in the widget section below.
"referenceLines": [ { "color": "#963CE9", "label": "Bindings Rock", "value": 5000000 } ]
As mentioned above the use case we are working with is to make the reference line dynamic, the value should be the average of Amount. We will create a hidden step that calculates the average Amount and we will rely upon the default faceting to recalculate the average amount when something is selected on the dashboard. The query of the hidden step called ‘Avg_1’ is below.
"query": { "measures": [ [ "avg", "Amount" ] ] }
Let’s tie it all together with the bindings in the value and text of the reference line. These are pretty simple bindings that we covered in part 1 of this blog series; one result binding and one selection binding.
"label": "{{column(Map_1.selection, ["Account.BillingState"]).asString()}}", "value": "{{cell(Avg_1.result, 0, "avg_Amount").asString()}}"
Now let’s have a look at have we can use some of the data manipulation functions.
Coalesce
In my opinion, the most commonly used data manipulation function is ‘coalesce’. This is especially useful for selection bindings, because what if no selection has been made? What value should then be passed to the binding? The coalesce function gives us the opportunity to define a default value should nothing be selected. If you try the above dashboard now you will notice that the text in the reference line is “null” unless you select a state on the map.
The coalesce function consist of the first priority value and then the default value like below.
coalesce(1st priority value, default value)
Now in our example, the binding is our first priority, meaning if something is selected show that. But if nothing has been selected we want to show the text “All States”. We want to make sure this value happens before our data serialization, so it can take either value and show it in the format we want.
"{{coalesce(column(Map_1.selection, ["Account.BillingState"]), "All States").asString()}}"
Notice that the data selection is our first priority value, hence why we have the column selection function as the first priority. The default value is as mentioned “All States”, which has been escaped in the binding.
Remember the default value doesn’t have to be static, you could use a binding for this as well!
Join
Now, what if I change my map step to allow multiple selections? Below you can see how I’ve selected the ‘step’ tab of my Map_1 step and allowed for multiple selections.
You will see that when we now try to select a few states on the map the output is in an array each value being in double quotes and separated by a comma.
This is not really how we want the reference line to look, it would look nicer without the array and the double quotes. Furthermore, it would be nice to have a space between each comma. Cosmetics, but it’s important. I can use the join function, which allows me to take an array and convert it into a string. It also allows me to define how each value is separated.
The syntax for the join function is to first define the array that we need to convert into a string followed by how we want to separate each value. This separator can be anything you can pick a comma or maybe choose to write “and” between each value.
join(array input, separator)
Looking at our selection binding, we need to add the join after the coalesce as the join is part of how we need to interpret the first priority value.
"{{coalesce(join(column(Map_1.selection, ["Account.BillingState"]), ", "), "All States").asString()}}"
In our example above the column data selection is our array and becomes the first part of our join function. Each value should be separated by a comma and space, which is the second part of our join function.
Using the coalesce and the join data manipulation function allows us to have a default value if nothing is selected, but when one or multiple are selected the value is no longer in an array and it’s neatly separated by a comma.
So if you have use cases where the format is not quite how it needs to be, remember to check out the data manipulation functions in the documentation.
Next, is the final part of this demystifying bindings blog series. The 9th part will take all the examples covered and give it away for free (hooray!) for you to install in your own developer org, so you at any time can look at the live examples.
Thanks for the post Rikke. Handling null return on a column binding had been vexing me for a while, and I could not figure just the right code. After seeing your post, the code seems obvious of-course 🙂
Great stuff thank you. The syntax for binding with coalesce was throwing me off.
Hi Rikke, I have created a binding to filter a table by a picklist selection and I am trying to use coalese to make sure the the table displays all values of the picklist when the filter toggle is not selected. Can I use ‘all’ or ‘null’ to make sure the filter is not applied and the table displays?
I am having the same issue, and I don’t think coalesce is the right method? Would love to see a response here!
Hi Micah, I actually managed to solve this using Coalese. I used the ‘in’ filter on a table:
Filter:
“LeadId.Status”,
[
“{{coalesce(cell(static_1.selection, 0, \”Text2\”), \”1 – Target\”).asString()}}”,
“{{coalesce(cell(static_1.selection, 0, \”Text3\”), \”1 – Target\”).asString()}}”,
“{{coalesce(cell(static_1.selection, 0, \”Text4\”), \”1 – Target\”).asString()}}”
],
“in”
Static Table:
Display Text2 Text3 Text4
Active Leads 2 – Engage 4 – Discover 5 – Activate
Converted Converted Converted Converted
Hope this helps.
Thanks!