Skip to content

{#with ...} block #6951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
accuser opened this issue Nov 21, 2021 · 1 comment
Closed

{#with ...} block #6951

accuser opened this issue Nov 21, 2021 · 1 comment

Comments

@accuser
Copy link

accuser commented Nov 21, 2021

Describe the problem

Objects with many fields or longer names can cause markup to become noisy. Consider this journalArticle prop:

  <script lang="ts">
    export let journalArticle: {
      abstract: string;
      authors: string;
      journal: string;
      linkTitle: string;
      publishedAt: string;
      slug: string;
      title: string;
    };
  </script>

when rendering:

    <h1>{journalArticle.title}</h1>
    <p>{journalArticle.authors}</p>
    <p>{journalArticle.abstract}</p>
    <p>Published {journalArticle.publishedAt} in {journalArticle.journal}</p>

The journalArticle prop is referred to five times in the simple example above, and whilst each reference is important, adds little to the clarity of the markup.

Describe the proposed solution

The {#each ...} block introduces a mechanism to iterate over an array of elements and deconstruct each:

  <ul>
    {#each journalArticles as {slug, linkTitle}}
      <li>
        <a href={slug}>{linkTitle}</a>
      </li>
    {/each}
  </ul>

A similar approach could be adopted for single objects, deconstructing the object for the scope of the block. Consider the example above in a new #with block:

  {#with journalArticle as {abstract, authors, journal, title}}
    <h1>{title}</h1>
    <p>{authors}</p>
    <p>{abstract}</p>
    <p>Published {publishedAt} in {journal}</p>
  {/with}

The deconstructed fields are local to the block, and are deconstructed because they are used in the block.

#with could also be used with arrays:

  {#with journalArticles as [featuredArticle, ...rest]}
    {#with featuredArticle as {abstract, authors, journal, title}}
      <h1>{title}</h1>
      <p>{authors}</p>
      <p>{abstract}</p>
      <p>Published {publishedAt} in {journal}</p>
    {/with}
    <ul>
      {#each rest as {slug, linkTitle}}
      <li>
        <a href={slug}>{linkTitle}</a>
      </li>
    {/each}
  {/with}

Alternatives considered

It is obviously possible to deconstruct a prop (or other object) in the component script:

  <script lang="ts">
    export let journalArticle: {
      abstract: string;
      authors: string;
      journal: string;
      linkTitle: string;
      publishedAt: string;
      slug: string;
      title: string;
    };

  const { abstract, authors, journal, linkTitle, publishedAt, slug, title } = journalArticle;

However, this exposes all deconstructed fields to the whole component. A local, block-scoped deconstruction using a #with block is more purposeful.

Importance

would make my life easier

@Conduitry
Copy link
Member

See #4601. This has been previously rejected in favor of a feature suggestion of a {@const} block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants