1

I am creating a comparison between popular javascript frameworks and need to create an HTML element for each object returned from an api.

const frameworks = [
  {
    name: "angular"
  },
  {
    name: "ember"
  },
  {
    name: "react"
  },
  {
    name: "vue"
  }
];

To keep it simple I just have an array of objects (this is simplified for readability).

I have a function to loop over this array and for now it's just printing the name of the framework to the console. If I want to create this HTML element (just a bootstrap card) for each item in the loop, what would be the best way to do it?

frameworks.forEach(fw => {
    console.log(fw);
  });

Just a very simple forEach function.

<div class="card" style="width: 18rem;">
  <img class="card-img-top" src=".../100px180/?text=Image cap" alt="Card image cap">
  <div class="card-body">
    <h5 class="card-title">Card title</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
  </div>
  <ul class="list-group list-group-flush">
    <li class="list-group-item">Cras justo odio</li>
    <li class="list-group-item">Dapibus ac facilisis in</li>
    <li class="list-group-item">Vestibulum at eros</li>
  </ul>
  <div class="card-body">
    <a href="#" class="card-link">Card link</a>
    <a href="#" class="card-link">Another link</a>
  </div>
</div>

I am trying to do this in vanilla JS otherwise I would just use React. This just seems a bit cumbersome. Is the best way to do it is to scaffold this as a template with the createElement() function?

3 Answers 3

1

For plain javascript :

const frameworks = [
  {
    name: "angular"
  },
  {
    name: "ember"
  },
  {
    name: "react"
  },
  {
    name: "vue"
  }
];

frameworks.forEach( framework => {
  const card = `<div class="card" style="width: 18rem;">
  <img class="card-img-top" src=".../100px180/?text=Image cap" alt="Card image cap">
  <div class="card-body">
    <h5 class="card-title">${framework.name}</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
  </div>
  <ul class="list-group list-group-flush">
    <li class="list-group-item">Cras justo odio</li>
    <li class="list-group-item">Dapibus ac facilisis in</li>
    <li class="list-group-item">Vestibulum at eros</li>
  </ul>
  <div class="card-body">
    <a href="#" class="card-link">Card link</a>
    <a href="#" class="card-link">Another link</a>
  </div>
</div>`
  const ele = document.createElement('div');
  ele.innerHTML = card;
  document.body.appendChild(ele.firstChild);
})
Sign up to request clarification or add additional context in comments.

Comments

0

If you don't have to add any event listeners, I'd suggest insertAdjacentHTML():

const frameworks = [
  {
    name: "angular"
  },
  {
    name: "ember"
  },
  {
    name: "react"
  },
  {
    name: "vue"
  }
];

frameworks.forEach( framework => 
  document.body.insertAdjacentHTML("beforeend", 
  `<div class="card" style="width: 18rem;">
  <img class="card-img-top" src=".../100px180/?text=Image cap" alt="Card image cap">
  <div class="card-body">
    <h5 class="card-title">${framework.name}</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
  </div>
  <ul class="list-group list-group-flush">
    <li class="list-group-item">Cras justo odio</li>
    <li class="list-group-item">Dapibus ac facilisis in</li>
    <li class="list-group-item">Vestibulum at eros</li>
  </ul>
  <div class="card-body">
    <a href="#" class="card-link">Card link</a>
    <a href="#" class="card-link">Another link</a>
  </div>
</div>`))

Comments

0

I'd suggest you using reduce instead of forEach.
Prepare your HTML as a string, then update innerHTML of the parent element. It would be way faster than adding cards one-by-one.

See the snippet below:

const frameworks = [{
    name: "angular"
  },
  {
    name: "ember"
  },
  {
    name: "react"
  },
  {
    name: "vue"
  }
];

document.querySelector('.content')
  .innerHTML = frameworks.reduce((a, fw) => a +=
  `<div class="card" style="width: 18rem;">
  <img class="card-img-top" src=".../100px180/?text=Image cap" alt="Card image cap">
  <div class="card-body">
    <h5 class="card-title">${fw.name}</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
  </div>
  <ul class="list-group list-group-flush">
    <li class="list-group-item">Cras justo odio</li>
    <li class="list-group-item">Dapibus ac facilisis in</li>
    <li class="list-group-item">Vestibulum at eros</li>
  </ul>
  <div class="card-body">
    <a href="#" class="card-link">Card link</a>
    <a href="#" class="card-link">Another link</a>
  </div>
</div>`, ''
);
.content {
  display: flex;
  flex-flow: row wrap;
}

.card {
  margin: .5rem;
  padding: 1rem;
  background: #fec
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="content"></div>

Hope it helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.