Skip to content

Creating a web component the makes API requests

Italo Marcel edited this page Oct 30, 2018 · 3 revisions

Introduction

This tutorial will guide you through the steps of creating a web component that makes API requests.

withState

withState() Is a decorator that encapsulates a class and give access to the set of states in the component. When state changes, the component responds by re-rendering.

withState

WithRequest() Is a decorator that allows the insertion of parameters by name that will be used in the request to api.

Development

You can combine withState and withRequest to make the attributes used in the request reflect on the state of the component.

Usage example:

import { SlingElement, html, withRequest, withSetState } from 'sling-framework';

export const RandomUser = (Base = class {}) =>
  class extends withSetState(withRequest(Base)) {
    constructor() {
      super();
      this.state = {
        name: '',
        picture: null,
      };
    }

    static get properties() {
      return {
        state: {
          type: Object,
          reflectToAttribute: false,
        },
        isLoading: {
          type: Boolean,
          reflectToAttribute: false,
        },
        requestErrors: {
          type: Array,
          reflectToAttribute: false,
        },
      };
    }

    static get requestParamNames() {
      return ['nat'];
    }

    requestParamsChangedCallback(requestParams) {
      if (requestParams.nat != null) {
        this.fetchUser(requestParams);
      }
    }

    fetchUser({ nat }) {
      this
        .request(window.fetch(`https://randomuser.me/api/?nat=${nat}`))
        .then(async (response) => {
          const data = await response.json();
          const [user] = data.results;

          this.setState({
            name: `${user.name.first} ${user.name.last}`,
            picture: user.picture.large,
          });
        });
    }

    render() {
      return html`
        <style>
          img { width: 128px; height: 128px; }
        </style>
        ${this.requestErrors.map(error => html`<p>${error}</p>`)}
        <div>
          ${this.isLoading ? html`<p><em>loading</em></p>` : ''}
          ${this.state.picture ? html`<img src="${this.state.picture}">` : ''}
          <h4>${this.state.name}</h4>
        </div>
      `;
    }
  }

window.customElements.define('random-user', RandomUser(SlingElement));