Patsch
Patsch

Reputation: 79

Javascript Template render function returns undefined

My render function returns undefined for each circle in data.
I have a variable amount of circles, thats why I need to map over all circles.
Is this the right way to call the render function ?
How can I achieve that the circles get returned correctly ?

JS

const d = data;

document.getElementById("gElement").innerHTML = `

    ${d.g.map((entry)=> {
        console.log(entry);

        return `
        <g class="${entry.class}" id="${entry.id}">

        <polygon 
           $points ="${entry.polygon.points}">
        </polygon>

        ${render(entry.circle)}

        </g>`
    }).join('')}`

    function render(circ){  
       `${circ.map((entry) =>{

            return`
            <circle
                cx = "${entry.cx}"
                cy = "${entry.cy}"
                r  = "${entry.r}"
                fill = "${entry.fill}">
            </circle>`

        }).join('')}`
    }  

data.json

 {
    "id": "gElement",
    "g": [
        {
            "class": "polygon",
            "id": "elements100",
            "polygon": {
                "points": "337,212.00000000000006,352.99999999999994,150,433.99999999999994,147.00000000000006,431,206.00000000000006"
            },
            "circle": [
                {
                    "cx": "337",
                    "cy": "212.00000000000006",
                    "r": "2",
                    "fill": "none"
                },
                {
                    "cx": "352.99999999999994",
                    "cy": "150",
                    "r": "2",
                    "fill": "none"
                },
                {
                    "cx": "433.99999999999994",
                    "cy": "147.00000000000006",
                    "r": "2",
                    "fill": "none"
                },
                {
                    "cx": "431",
                    "cy": "206.00000000000006",
                    "r": "2",
                    "fill": "none"
                }
            ]
         }
      ]
   }

Upvotes: 0

Views: 854

Answers (1)

Terry
Terry

Reputation: 66123

You can't nest template literals within each other, since the backticks will interfere with each other. Your best bet is to abstract the d.g.map((entry)=> { ... }) into a separate function, and then invoke that function within a template literal.

Also, within your render() function, you are not returning the joined array. It will return undefined and your circles will never be injected into your HTML. The following script should work:

document.getElementById("gElement").innerHTML = getParsedHtml(d);

    function getParsedHtml(data) {
      return data.g.map(entry => {
        return `
              <g class="${entry.class}" id="${entry.id}">

              <polygon 
                 points ="${entry.polygon.points}">
              </polygon>

              ${render(entry.circle)}

              </g>`;
       }).join('');
    }

    function render(circ) {
      return circ.map(entry => {
        return `
          <circle
              cx="${entry.cx}"
              cy="${entry.cy}"
              r="${entry.r}"
              fill="${entry.fill}">
          </circle>`;
      }).join('');
    }

I noticed that you have a $ prefix in the polygon's points attribute: I suppose that is a typo?

See proof-of-concept example below:

const d = {
  "id": "gElement",
  "g": [{
    "class": "polygon",
    "id": "elements100",
    "polygon": {
      "points": "337,212.00000000000006,352.99999999999994,150,433.99999999999994,147.00000000000006,431,206.00000000000006"
    },
    "circle": [{
        "cx": "337",
        "cy": "212.00000000000006",
        "r": "2",
        "fill": "none"
      },
      {
        "cx": "352.99999999999994",
        "cy": "150",
        "r": "2",
        "fill": "none"
      },
      {
        "cx": "433.99999999999994",
        "cy": "147.00000000000006",
        "r": "2",
        "fill": "none"
      },
      {
        "cx": "431",
        "cy": "206.00000000000006",
        "r": "2",
        "fill": "none"
      }
    ]
  }]
};

document.getElementById("gElement").innerHTML = getParsedHtml(d);

function getParsedHtml(data) {
  return data.g.map(entry => {
    return `
          <g class="${entry.class}" id="${entry.id}">

          <polygon 
             points ="${entry.polygon.points}">
          </polygon>

          ${render(entry.circle)}

          </g>`;
   }).join('');
}

function render(circ) {
  return circ.map(entry => {
    return `
      <circle
          cx="${entry.cx}"
          cy="${entry.cy}"
          r="${entry.r}"
          fill="${entry.fill}">
      </circle>`;
  }).join('');
}
svg {
  border: 1px solid #000;
  width: 250px;
  height: 250px;
}

polygon {
  fill: grey;
}
circle {
  fill: steelblue;
}
<svg viewBox="0 0 500 500">
  <g id="gElement"></g>
</svg>

Upvotes: 0

Related Questions