Apollo Elements Guides API Blog

Web Component Libraries: Polymer

Polymer is the OG web components library, and while it's now in maintenance (the library, not the project), it's still in use all over the web.

Installation

npm i -S @apollo-elements/polymer
yarn add @apollo-elements/polymer
pnpm add @apollo-elements/polymer

Import apollo-query, apollo-mutation, or apollo-subscription to bind data up into your Polymer elements.

Examples

These custom elements fire polymer-style *-changed events when the Apollo cache updates their state. They extend directly from HTMLElement so they're small in size, and their notifying properties make them perfect for use in Polymer templates.

Using <apollo-client> to Scope a Client to it's Children

This example uses <apollo-client> to create a client and assign it to <apollo-query>. There's no need to explicitly assign the client property, since <apollo-client> automatically sets the client on all it's deeply nested children.

import { PolymerElement, html } from '@polymer/polymer';
import '@apollo-elements/components/apollo-client';
import '@apollo-elements/polymer/apollo-query';

class HelloQueryElement extends PolymerElement {
  static get template() {
    return html`
      <apollo-client uri="/graphql">
        <apollo-query data="{{data}}" variables="[[variables]]">
          <script type="application/graphql">
            query HelloQuery($name: String, $greeting: String) {
              hello(name: $name, greeting: $greeting) {
                name
                greeting
              }
            }
          </script>
        </apollo-query>
      </apollo-client>

      <span id="hello">
        [[getGreeting(data)]], [[getName(data)]]!
      </span>
    `;
  }

  static get properties() {
    return {
      data: { type: Object },
      variables: {
        type: Object,
        value: () => ({
          name: 'Partner',
          greeting: 'Howdy',
        }),
      },
    };
  }

  getGreeting(data) {
    return data && data.hello && data.hello.greeting || 'hello';
  }

  getName(data) {
    return data && data.hello && data.hello.name || 'world';
  }
}

customElements.define('hello-query', HelloQueryElement);

Using Two-Way Binding to Set the Client

If you prefer, you can use Polymer's two-way binding to set an element's client property, instead of nesting the apollo elements under an <apollo-client> element.

<apollo-client uri="/graphql" client="{{ownClient}}"></apollo-client>
<apollo-client uri="https://api.spacex.land/graphql" client="{{spaceXClient}}"></apollo-client>

<apollo-query
    client="[[ownClient]]"
    data="{{helloData}}"
    variables="[[helloVariables]]">
  <script type="application/graphql">
    query HelloQuery($name: String, $greeting: String) {
      hello(name: $name, greeting: $greeting) {
        name
        greeting
      }
    }
  </script>
</apollo-query>

<apollo-query
    client="[[spacexClient]]"
    data="{{launchesData}}"
    variables="[[launchesVariables]]">
  <script type="application/graphql">
    query LaunchesQuery($sort: String = "launch_date_utc"){
      launches(sort: $sort, order: "desc") {
        launch_date_utc
        mission_name
        rocket {
          rocket_name
        }
      }
    }
  </script>
</apollo-query>

<p>
  <span>[[getGreeting(helloData)]]</span>,
  <span>[[getGreeting(helloData)]]</span>!
  Latest launch is
  <span>[[launchesData.launches.0.mission_name]]</span>.
</p>

Exports

@apollo-elements/polymer

import '@apollo-elements/polymer';
import {
  PolymerApolloElement,
  PolymerApolloQuery,
  PolymerApolloMutation,
  PolymerApolloSubscription
} from '@apollo-elements/polymer';