javascripthtmlpugcanvasjs

How to use interpolation for the ID attribute in Jade/Pug


I am trying to dynamically build chartContainers based on a MongoDB Database. For some background, I am using CanvasJS to create stock charts. I have a "stocks" variable I iterate through which is an array of all the elements in my database. This is my first web development project and my first time using javascript and pug so apologies if there is an obvious question. For reference, I built this project using this template

   console.log(stocks);
      for(const element of stocks){
        const str = 'chartContainer' + element.ticker;
        console.log(str);
        // Need to get data for that chart
        renderChart(data1, str, element.ticker);
      }

When this runs here is my log

Here is the render chart function(.js file)

function renderChart(chartData, chartContainer, Ticker = "Ticker") {
var chart1 = new CanvasJS.Chart(chartContainer,
  {
  title:{
  text: Ticker}, 
  axisY:{ title:"Price",minimum: 0, maximum: 6, includeZero: false},
  data: chartData });

  chart1.render();
  }

To make these "charts" show up on the webserver I need to create chart containers with the ID that I have defined earlier. This is in my pug file and it works as expected when I have two items in my database named TSLA and GOOGL.

  #chartContainerTSLA(style='width: 25%; height: 300px;display: inline-block;')
  #chartContainerGOOGL(style='width: 25%; height: 300px;display: inline-block;')

However, The issue I am having is I want to make the ticker at the end a string that I am changing. I was following this link for how to interpolate it but it is not working.

Some things I have tried:

  for result in stocks
    #chartContainer!{result.ticker}(style='width: 25%; height: 300px;display: inline-block;')

I also tried replacing the ! with a # and neither of them worked Here is the error that is thrown

 36|   for result in stocks
 37|     #chartContainer!{result.ticker}(style='width: 25%; height: 300px;display: inline-block;')
 ---------------------------^
 unexpected text "!{res"

I also tried

 for result in stocks
  - var containerName='chartContainer#{result.ticker}'
  #!{containerName}(style='width: 25%; height: 300px;display: inline-block;')

That threw the error

 36|     for result in stocks
 37|       - var containerName='chartContainer#{result.ticker}'
 38|       #!{containerName}(style='width: 25%; height: 300px;display: inline-block;')
 --------------^
 "!{containerName}" is not a valid ID.

I am looking for a way to generate these chart containers dynamically so I don't have to manually create chart containers every time something is entered into the database.


Solution

  • What you're looking for is called attribute interpolation in Pug.

    In Pug, the shorthand for giving an element an id attribute is the hash syntax you're already using and familiar with:

    div#chartContainer
    

    However, this can also be written using the regular attribute syntax, like so:

    div(id="chartContainer")
    

    In order to use interpolation within the id attribute, you must use the regular attribute syntax instead of the shorthand.

    This would be how you could use attribute interpolation with the id attribute in your loop, using either JS string concatenation or JS template strings:

    // using string concatenation
    for result in stocks
      div(id= 'chartContainer' + result.ticker, style='...')
    
    // using template strings
    for result in stocks
      div(id=`chartContainer${result.ticker}`, style='...')