skip to Main Content

I’ve got an array of comments, and want a part of them to be hidden, if hidden param is true, before a user clicks on a "load more" button.

But it doesn’t work properly, instead it adds hidden class to all comments but the last one.

async function comments(...arr) {
  let i = 0;
  const container = document.querySelector('.comments')

  function setHidden(h) {
    if (h === true) {
      $('.comment').addClass('hidden')
    } else {
      $('.comment').removeClass('hidden')
    }
  }

  for (let i of arr) {
    await setHidden(i.hidden)
    $(container).append(`<div class="comment">${i.comment}</div>`)
  }
}

comments({
  comment: 'hi'
}, {
  hidden: true,
  comment: 'how are you'
}, {
  hidden: true,
  comment: 'where are you from?'
});

2

Answers


  1. Firstly, as mentioned by @Andy in the comments, you don’t need async/await here, as setHidden() doesn’t return a promise.

    The reason your current logic doesn’t work for the last comment is because you haven’t added it to the DOM at the point you invoke the setHidden() function in the final loop iteration.

    Also note that the logic is flawed because all .comment elements will be hidden based on the state of the last i.hidden value. You should instead set the .hidden class on the .comment you create within the for loop, not all of them at once.

    It’s also a simple exercise to do this without jQuery; no point adding a library for a single line of code.

    function comments(...arr) {
      const container = document.querySelector('.comments');
    
      for (let comment of arr) {
        const div = document.createElement('div');
        div.classList.add('comment')
        comment.hidden && div.classList.add('hidden');
        div.textContent = comment.comment;
        container.appendChild(div);
      }
    }
    
    comments({
      comment: 'hi'
    }, {
      hidden: true,
      comment: 'how are you'
    }, {
      hidden: true,
      comment: 'where are you from?'
    });
    .hidden { display: none; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
    <h3>Comments:</h3>
    <div class="comments"></div>
    Login or Signup to reply.
  2. Following on from Rory’s answer, if you did want to use jQuery throughout (you’re mixing and matching with vanilla JS at the moment) you can.

    function comments(...arr) {
      
      const container = $('.comments');
    
      $.each(arr, (i, obj) => {
        const comment = $(`<div class="comment">div>`);
        if (obj.hidden) comment.addClass('hidden');
        comment.text(obj.comment);
        $(container).append(comment);
      });
    
    }
    
    comments({
      comment: 'hi'
    }, {
      hidden: true,
      comment: 'how are you'
    }, {
      hidden: true,
      comment: 'where are you from?'
    });
    .hidden { display: none; }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="comments"></div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search