Concatenate @key in handlebars each function

Good Day… Been struggling with this one for a while and will try to be as brief as possible.

Working in Javascript on an experience page (below the body of the page in a tag. I have an {{each}} function that generates the required code to display several charts displaying historical data.

I an able to use the {{@key}} tool to dynamically populate the chart data. Everything is working except for the chart labels. I can get the required data by using the valueByKey Format Helper.

Here is a sample payload and the expression used to get the data:

{
  "tags": [
    {
      "key": "ai1Name",
      "value": "Analog Input 1"
    },{
      "key": "ai2Name",
      "value": "AI Two"
    },{
      "key": "temp1Name",
      "value": "Refrigerator One"
    },{
      "key": "temp2Name",
      "value": "Cold Storage"
    },{
      "key": "temp3Name",
      "value": "Temperature Sensor 3"
    },{
      "key": "temp4Name",
      "value": "Temp Four"
    }
  ]
}

Let’s assume that the current value of {{@key}} = 'temp2'

This Works

var {{@key}}ValueByKey = '{{valueByKey @root.pageData.device.compositeState "temp2Name" "key" "value"}}';

& will give a result of:

var temp2ValueByKey = "Cold Storage"

The issue is that I really need to type it as:

var {{@key}}ValueByKey = '{{valueByKey @root.pageData.device.compositeState "{{@key}}Name" "key" "value"}}';

This would create the above example but would also create var ai1ValueByKey = "Analog Input 1" and so on for each item.

I have also tried to create variables and plug them in, example:

var thisLabel = '{{@key}}Name';

The variable does create the expected value but it cannot be used in the valueByKey Format Helper.

A few possible solutions would be:

  • Be able to plug a variable instead of a string as the key that we are searching for.
  • Be able to concatenate the {{@key}} value within the valueByKey helper.
  • Call a handlebars function to do the concatenating. example:
Handlebars.registerHelper('concat', function () {
    return Array.prototype.slice.call(arguments, 0, -1).join('');
});

Can anything be done to avoid hardcoding all of our charts?

Thanks so much!

Pardon the pun but the key here is the {{template}} helper and the use of sub-helpers.

var {{@key}}ValueByKey = '{{valueByKey @root.pageData.device.compositeState (template '{{this}}Name' @key) "key" "value"}}';

This gives you the variable you’re looking for by rendering that argument as a regular Handlebars template ({{this}}Name) against context data (@key).

Alternatively, if changing the shape of the response is an option, you can change your Device: Get Node (assuming that’s generating your compositeState object) to return your tags and attributes as an object map, which you could then probably use the built-in {{lookup}} Handlebars helper.

Based on everything you’ve posted here, it looks like you are storing the human-friendly names of your attributes on device tags. I would recommend moving those to attribute tags instead. Then, you could iterate over your attributes and have the value you seek right there in the same object.

Excellent… I am impressed. I did notice the “template” format helper but could not figure out how it applied here. Thank you so much for the fast response and incredibly useful tools!

1 Like