Skip to content
On this page

Let's review

src/brewery-app.js

js
import { LitElement, html, css } from 'lit';
import 'https://unpkg.com/@material/mwc-button?module';
import './brewery-template.js';

class BreweryApp extends LitElement {
  static get styles() {
    return css`
      :host {
        display: block;
        max-width: 60em;
        margin-inline: auto;
        padding: 2rem;
      }
      ul {
        list-style-type: none;
        padding-left: 0;
      }
      li + li {
        border-top: 1px solid #ccc;
        margin-block: 1.5rem;
      }
    `
  }

  static get properties() {
    return {
      loading: { type: Boolean },
      breweries: { type: Array },
      filter: { type: String },
    };
  }

  connectedCallback() {
    super.connectedCallback();

    if (!this.breweries) {
      this.fetchBreweries();
    }
  }

  async fetchBreweries() {
    this.loading = true;
    const response = await fetch('https://api.openbrewerydb.org/breweries/search?query=minneapolis');
    const jsonResponse = await response.json();
    this.breweries = jsonResponse;
    this.loading = false;
  }

  render() {
    if (this.loading) {
      return html` <p>Loading...</p> `;
    }

    const totalVisited = this.breweries.filter(b => b.visited).length;
    const totalNotVisited = this.breweries.length - totalVisited;
    const breweries = this.breweries.filter(brewery => {
      if (!this.filter) {
        return true;
      }
      return this.filter === 'visited' ? brewery.visited : !brewery.visited;
    });

    return html`
      <h1>Breweries App</h1>

      <h2>Breweries</h2>
      <p>(${totalVisited} visited and ${totalNotVisited} still to go)</p>

      <mwc-button @click=${() => {this.filter = null}}>Filter none</mwc-button>
      <mwc-button @click=${() => {this.filter = 'visited'}}>Filter visited</mwc-button>
      <mwc-button @click=${() => {this.filter = 'not-visited'}}>Filter not-visited</mwc-button>

      <ul>
        ${breweries.map(
          brewery => html`
            <li>
              <brewery-template
                .brewery="${brewery}"
                .toggleVisitedStatus=${() => this.toggleVisitedStatus(brewery)}>
              </brewery-template>
            </li>
          `,
        )}
      </ul>
    `;
  }

  toggleVisitedStatus(breweryToUpdate) {
    this.breweries = this.breweries.map(brewery => brewery === breweryToUpdate
      ? { ...brewery, visited: !brewery.visited }
      : brewery);
  }
}

customElements.define('brewery-app', BreweryApp);
import { LitElement, html, css } from 'lit';
import 'https://unpkg.com/@material/mwc-button?module';
import './brewery-template.js';

class BreweryApp extends LitElement {
  static get styles() {
    return css`
      :host {
        display: block;
        max-width: 60em;
        margin-inline: auto;
        padding: 2rem;
      }
      ul {
        list-style-type: none;
        padding-left: 0;
      }
      li + li {
        border-top: 1px solid #ccc;
        margin-block: 1.5rem;
      }
    `
  }

  static get properties() {
    return {
      loading: { type: Boolean },
      breweries: { type: Array },
      filter: { type: String },
    };
  }

  connectedCallback() {
    super.connectedCallback();

    if (!this.breweries) {
      this.fetchBreweries();
    }
  }

  async fetchBreweries() {
    this.loading = true;
    const response = await fetch('https://api.openbrewerydb.org/breweries/search?query=minneapolis');
    const jsonResponse = await response.json();
    this.breweries = jsonResponse;
    this.loading = false;
  }

  render() {
    if (this.loading) {
      return html` <p>Loading...</p> `;
    }

    const totalVisited = this.breweries.filter(b => b.visited).length;
    const totalNotVisited = this.breweries.length - totalVisited;
    const breweries = this.breweries.filter(brewery => {
      if (!this.filter) {
        return true;
      }
      return this.filter === 'visited' ? brewery.visited : !brewery.visited;
    });

    return html`
      <h1>Breweries App</h1>

      <h2>Breweries</h2>
      <p>(${totalVisited} visited and ${totalNotVisited} still to go)</p>

      <mwc-button @click=${() => {this.filter = null}}>Filter none</mwc-button>
      <mwc-button @click=${() => {this.filter = 'visited'}}>Filter visited</mwc-button>
      <mwc-button @click=${() => {this.filter = 'not-visited'}}>Filter not-visited</mwc-button>

      <ul>
        ${breweries.map(
          brewery => html`
            <li>
              <brewery-template
                .brewery="${brewery}"
                .toggleVisitedStatus=${() => this.toggleVisitedStatus(brewery)}>
              </brewery-template>
            </li>
          `,
        )}
      </ul>
    `;
  }

  toggleVisitedStatus(breweryToUpdate) {
    this.breweries = this.breweries.map(brewery => brewery === breweryToUpdate
      ? { ...brewery, visited: !brewery.visited }
      : brewery);
  }
}

customElements.define('brewery-app', BreweryApp);

src/brewery-template.js

js
import { LitElement, html, css } from 'lit';
import 'https://unpkg.com/@material/mwc-button?module';

class BreweryTemplate extends LitElement {
  static get styles() {
    return css`
      :host {
        position: relative;
      }
      .check {
        position: absolute;
        left: -1.5rem;
      }
    `
  }

  static get properties() {
    return {
      brewery: { type: Object },
      toggleVisitedStatus: {},
    };
  }

  render() {
    return html`
      <span class="check">${this.brewery.visited ? '✅' : ''}</span>
      <h3> ${this.brewery.name}</h3>
      <p><a href="${this.brewery.website_url}">${this.brewery.website_url}</a></p>
      <mwc-button @click=${this.toggleVisitedStatus}>
        Mark as ${this.brewery.visited ? 'not-visited' : 'visited'}
      </mwc-button>
  `;
  }
}

customElements.define('brewery-template', BreweryTemplate);
import { LitElement, html, css } from 'lit';
import 'https://unpkg.com/@material/mwc-button?module';

class BreweryTemplate extends LitElement {
  static get styles() {
    return css`
      :host {
        position: relative;
      }
      .check {
        position: absolute;
        left: -1.5rem;
      }
    `
  }

  static get properties() {
    return {
      brewery: { type: Object },
      toggleVisitedStatus: {},
    };
  }

  render() {
    return html`
      <span class="check">${this.brewery.visited ? '✅' : ''}</span>
      <h3> ${this.brewery.name}</h3>
      <p><a href="${this.brewery.website_url}">${this.brewery.website_url}</a></p>
      <mwc-button @click=${this.toggleVisitedStatus}>
        Mark as ${this.brewery.visited ? 'not-visited' : 'visited'}
      </mwc-button>
  `;
  }
}

customElements.define('brewery-template', BreweryTemplate);

Licenced MIT