1.0.1 • Published 1 year ago

svelte-apollo-wrappers v1.0.1

Weekly downloads
-
License
ISC
Repository
-
Last release
1 year ago

svelte-apollo-wrappers

Documentation based on svelte-apollo library. Svelte integration for Apollo GraphQL without Svelte context usage. Support multiple GraphQL docuemnts as arguments.

Example

The following simple example shows how to run a simple query with svelte-apollo.

/* main.ts */
import { ApolloClient } from "@apollo/client/core";
import { setClient } from "svelte-apollo-wrappers";

// 1. Create an Apollo client and pass it to all child components
//    (uses svelte's built-in context)
const client = new ApolloClient({
  /* ... */
});
setClient(client);
<!-- Books.svelte -->
<script>
  import { query } from "svelte-apollo-wrappers";
  import GET_BOOKS from "./GET_BOOKS.graphql";

  // 2. Execute the GET_BOOKS GraphQL query using the Apollo client
  //    -> Returns a svelte store of promises that resolve as values come in
  const books = query(GET_BOOKS);
  
  // 3. Refetch query each 15 seconds
  //    books.query is original result from apolloClient.watchQuery call
  setInterval(() => books.query.refetch(), 15000);
</script>

<!-- 3. Use $books (note the "$"), to subscribe to query values -->
{#if $books.loading}
  Loading...
{:else if $books.error}
  Error: {$books.error.message}
{:else}
  {#each $books.data.books as book}
    {book.title} by {book.author.name}
  {/each}
{/if}

API

# query(document, options)

Query an Apollo client, returning a readable store of result values. Uses Apollo's watchQuery, for fetching from the network and watching the local cache for changes.

<script>
  import { query } from "svelte-apollo-wrappers";
  import GET_BOOKS from "./GET_BOOKS.graphql";

  const books = query(GET_BOOKS, {
    // variables, fetchPolicy, errorPolicy, and others
  });

  function reload() {
    books.query.refetch();
  }
</script>

<ul>
  {#if $books.loading}
    <li>Loading...</li>
  {:else if $books.error}
    <li>ERROR: {$books.error.message}</li>
  {:else}
    {#each $books.data.books as book (book.id)}
      <li>{book.title} by {book.author.name}</li>
    {/each}
  {/if}
</ul>

<button on:click="{reload}">Reload</button>

Reactive variables are supported with refetch:

<script>
  import { query } from "svelte-apollo-wrappers";
  import { SEARCH_BY_AUTHOR } from "./queries";

  export let author;
  let search = "";

  const books = query(SEARCH_BY_AUTHOR, {
    variables: { author, search },
  });

  // `books` is refetched when author or search change
  $: books.query.refetch({ author, search });
</script>

Author: {author}
<label>Search <input type="text" bind:value="{search}" /></label>

<ul>
  {#if $books.loading}
    <li>Loading...</li>
  {:else if $books.error}
    <li>ERROR: {$books.error.message}</li>
  {:else if $books.data}
    {#each $books.data.books as book (book.id)}
      <li>{book.title}</li>
    {/each}
  {:else}
    <li>No books found</li>
  {/if}
</ul>

# mutation(document, options)

Prepare a GraphQL mutation with the Apollo client, using Apollo's mutate. mutation() call returns async function to execute mutation; Returned function has subscribe method, so you can use it as svelte store ({ data, loading, error }). You can set mutation options as second argument of mutation() call, them will use as default in all executions of resulted mutation function. You can specify them for every call as first argument.

<script>
  import { mutation } from "svelte-apollo-wrappers";
  import ADD_BOOK from "./ADD_BOOK.graphql";

  const addBook = mutation(ADD_BOOK);
  let title = "";
  let author = "";

  $: ({ data, error, loading } = $addBook);

  async function handleSubmit() {
    try {
      await addBook({ variables: { title, author } });
    } catch (error) {
      // TODO
    }
  }
</script>

<form on:submit|preventDefault="{handleSubmit}">
  <label for="book-author">Author</label>
  <input type="text" id="book-author" bind:value="{author}" />

  <label for="book-title">Title</label>
  <input type="text" id="book-title" bind:value="{title}" />

  <button type="submit" loading="{loading}">Add Book</button>
</form>
{#if data}
Done!
{:else if error}
Error!
{/if}

# lazyQuery(document, options)

Prepare a GraphQL lazyQuery with the Apollo client, using Apollo's query. lazyQuery() call returns async function to execute query; Returned function has subscribe method, so you can use it as svelte store ({ data, loading, error }). You can set query options as second argument of lazyQuery() call, them will use as default in all executions of resulted query function. You can specify them for every call as first argument.

<script>
  import { lazyQuery } from "svelte-apollo-wrappers";
  import GET_BOOK from "./GET_BOOK.graphql";

  const getBook = lazyQuery(GET_BOOK);
  let title = "";
  let author = "";

  $: ({ data, error, loading } = $getBook);
</script>

<button on:click="{getBook}">Fetch book</button>
{#if data}
  Fetched: {data}
{:else if error}
  Error: {error}
{:else if loading}
  Loading
{/if}

# subscribe(document, options)

Subscribe using an Apollo client, returning a store that is compatible with {#await $...}. Uses Apollo's subscribe.

<script>
  import { subscribe } from "svelte-apollo-wrappers";
  import NEW_BOOKS from "./NEW_BOOKS.graphql";

  const newBooks = subscribe(NEW_BOOKS);
</script>

{#if $newBooks.loading}
  Waiting for new books...
{:else if $newBooks.data}
  New Book: {$newBooks.data.book}
{/if}

# setClient(client)

Set an Apollo client for all wrappers.

<!-- Parent.svelte -->
<script>
  import { setClient } from "svelte-apollo-wrappers";
  import client from "./client";

  setClient(client);
</script>

# getClient()

Get an Apollo client.

<!-- Child.svelte -->
<script>
  import { getClient } from "svelte-apollo-wrappers";

  const client = getClient();
</script>

FEATURES

# arrayed documents

You can use array of graphql documents as document argument for every wrappers. List of docuemnts will be merged in one document. Make sure that you dont have operations with the same name in different docuemnts. All wrappers options includes possible option operationName which will be usaed as a name for resulted document.

import QUERY_ONE from "./QUERY_ONE.graphql";
import QUERY_TWO from "./QUERY_TWO.graphql";
import { query } from "svelte-apollo-wrappers";

const queryStore = query([QUERY_ONE, QUERY_TWO]);

# Typescript

All wrappers are "typescripted". Usage the same as in ApolloClient.["watchQuery" / "query" / ...]. Supporting of TypedDocuemnts. If you are using graphql-codegen for generate types for GraphQL files the library will use this types.