Svelte iterate over array of keys and get key from object

Viewed 809

I have an object comments:

let comments = {"id1": ..., "id2: ..., ...};

I then have an array commentsSortedByDate:

let commentsSortedByDate = ["id2", "id1", ...];

I would like to iterate over these comments. This is what I've tried:

{#each commentsSortedByDate as commentId}
    <script> let comment = comments[commentId]; </script>
    <div class="comment" class:new={comment.isNew}> ... </div>
{/each}

This does not work. How can I define this comment variable in the loop so that I can access it multiple times without having to type comments[commentId] each time?

4 Answers

Right now there's no way to do this another way than what you propose (the each hack or always doing comments[commentId]). There's a incoming new feature for Svelte though which will make this possible: Using @const in markup. This is not implemented yet, but when it is, you can do this:

{#each commentsSortedByDate as commentId}
    {@const comment = comments[commentId]}
    <div class="comment" class:new={comment.isNew}> ... </div>
{/each}

Or you could simply remap your input array on the fly and iterate over comment objects rather than ids:

{#each commentsSortedByDate.map(id => comments[id]) as comment}
    <div class="comment" class:new={comment.isNew}> ... </div>
{/each}

I have come up with a hackish solution, but I will not be accepting this as a proper answer.

{#each commentsSortedByDate as commentId}
    {#each [comments[commentId]] as comment}
        <div class="comment" class:new={comment.isNew}> ... </div>
    {/each}
{/each}

Are you looking to do something like this?

<script>
  let commentsSortedByDate = ["id2", "id1"];
  let comments = {
    id1: {
      text: "lorem",
    },
    id2: {
      text: "ipsum",
    },
  };
</script>

<h2>
    Comments
</h2>
{#each commentsSortedByDate as comment}
  <ul>
    <li>
            {comment}: {Object.values(comments[comment])}
    </li>
  </ul>
{/each}

Related