GithubHelp home page GithubHelp logo

aruntk / polymer-apollo Goto Github PK

View Code? Open in Web Editor NEW
78.0 9.0 7.0 92 KB

๐Ÿš€ Polymer Apollo Integration

License: MIT License

JavaScript 100.00%
polymer-components apollo polymer-apollo apollo-client apollo-query

polymer-apollo's Introduction

Note: For Polymer 1.x checkout branch 1.x

Polymer-Apollo

Join the chat at https://gitter.im/aruntk/polymer npm npm

Polymer apollo integration.

Examples

GitHunt-Polymer - An example of a client-side app built with Polymer and Apollo Client.

NEWS App - A news app built using polymer-apollo

Polymer Apollo Frontpage App - Polymer Apollo Hello World app

Polymer Apollo Meteor App - Github api app using polymer-apollo meteor and synthesis

Table of contents

Installation

npm install --save polymer-apollo apollo-client

Usage

Configuration

//config.js
import ApolloClient, { createNetworkInterface, addTypename } from 'apollo-client';

// Create the apollo client
export const apolloClient = new ApolloClient({
  networkInterface: createNetworkInterface({
    uri: 'http://localhost:8080/graphql',
    transportBatching: true,
  })
});

Usage in components

//my-element.js
// if you want the es5 compiled version use
// import { PolymerApolloMixin } from 'polymer-apollo/es5';
import { PolymerApolloMixin } from 'polymer-apollo';
import { apolloClient } from './config.js';

class MyElement extends PolymerApolloMixin({apolloClient}, Polymer.Element) {
    static get is() {
        return 'my-element'
    }

    get apollo() {
        // Apollo specific options
    }
    ...
});

You can access the apollo-client instance with this.$apollo.client in all your polymer components.

Queries

In the apollo object, add an attribute for each property you want to feed with the result of an Apollo query.

Simple query

Use gql to write your GraphQL queries:

import gql from 'graphql-tag';

Put the gql query directly as the value:

get apollo() {
  return {
    // Simple query that will update the 'hello' polymer property
    hello: gql`{hello}`,
  };
}

Don't forget to initialize your property in your polymer component:

//my-element.js
...
properties : {
    // Initialize your apollo data
    hello: String,
},
...

Server-side, add the corresponding schema and resolver:

export const schema = `
type Query {
  hello: String
}

schema {
  query: Query
}
`;

export const resolvers = {
  Query: {
    hello(root, args, context) {
      return "Hello world!";
    },
  },
};

For more info, visit the apollo doc.

You can then use your property as usual in your polymer component:

<!--my-element.js-->
<dom-module id="my-element">
<template>
  <div class="apollo">
    <h3>Hello</h3>
    <p>
      {{hello}}
    </p>
  </div>
</template>
</dom-module>

Query with parameters

You can add variables (read parameters) to your gql query by declaring query and variables in an object:

Options can be computed properties or static.

Initial values of variables should be given if options are computed, since polymer options wont be triggered if arguments are undefined, which maybe the case during first rendering.

eg

...
static get properties() {
  return {
    computedProp: {
      type: Object,
      computed: 'computeFn(prop1, prop2)'
    }
  };
}
get apollo() {
  return {
    query1: {
      query: someQuery,
      // watches prop1 and prop2 changes
      // you should either initialize values of prop1,prop2 == !undefined or 
      // set an initial value to variables property
      variables: {
        var1: 'blah',
        var2: 'blah blah',
      },
      options: 'computedProp',
    }
  };
}
computeFn: function(prop1, prop2) {
  return { variables: { var1: prop1, var2: prop2 + 10 } };
}
...

. In this graphql variables var1 and var2 change when the polymer properties prop1 and prop2 change (similar to computed feature);

...
static get properties() {
  return {
    computedProp: {
      type: Object,
      computed: 'computeFn(prop1, prop2)'
    }
  };
}
// Apollo-specific options
get apollo() {
  return {
    // Query with parameters
    ping: {
      // gql query
      query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
      options: 'computedProp',
      variables: {
        message: '',
      },
    },
  };
}
computedFn: function(prop1, prop2) {
  return { variables: { message: `${prop1} ping...`} };
}

In the above example you can use the apollo watchQuery options in the property ping or in the computed function return, like:

  • forceFetch
  • fragments
  • returnPartialData
  • pollInterval
  • ...

See the apollo doc for more details.

For example, you could add the forceFetch apollo option like this:

static get properties() {
  return {
    computedProp: {
      type: Object,
      computed: 'computeFn(prop1, prop2)'
    }
  };
}

get apollo() {
  // Query with parameters
  return {
    pingQuery: {
    query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
    options: 'computedProp',
    variables: {
      message: 'blah',
    },
    skip: true,
    // Additional options here. static.
    forceFetch: true,
  };
  }
}
computedFn: function(prop1, prop2) {
  // Additional options if added here becomes reactive
  return {
    variables: {
      message: prop1,
    },
    skip: prop2,
  };
}

Don't forget to initialize your property in your polymer component.

//my-element.js
...
static get properties() {
    // Initialize your apollo data
    ping: String,
},
...

Server-side, add the corresponding schema and resolver:

export const schema = `
type Query {
  ping(message: String!): String
}

schema {
  query: Query
}
`;

export const resolvers = {
  Query: {
    ping(root, { message }, context) {
      return `Answering ${message}`;
    },
  },
};

And then use it in your polymer component:

<dom-module id="my-element">
<template>
  <div class="apollo">
    <h3>Ping</h3>
    <p>
      {{ping}}
    </p>
  </div>
</template>
</dom-module>

options

Options can be added in two ways - computed and static.

For computed options you may want to give initial values since

computing function is not invoked until all dependent properties are defined (!== undefined). So each dependent properties should have a default value defined in properties (or otherwise be initialized to a non-undefined value) to ensure the property is computed.

from polymer doc https://www.polymer-project.org/1.0/docs/devguide/observers#computed-properties

computed eg.

...
static get properties() {
  return {
    computedProp: {
      type: Object,
      computed: 'computeFn(prop1, prop2)'
    }
  };
}
get apollo() {
  return {
  // Query with parameters
  ping: {
    query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
    options: 'computedProp',
    // Additional options here. static.
    forceFetch: true,
  };
  }
}
computedFn: function(prop1, prop2) {
  // Additional options if added here becomes reactive
  return {
    variables: {
      message: prop1,
    },
    skip: prop2,
  };
}

static eg.

get apollo() {
  return {
  // Query with parameters
  ping: {
    query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
    options: {
      variables: {
        message: 'hai',
      },
      skip: true,
    },
  },
    // Additional options here. static. you can add skip here also
    forceFetch: true,
  };
}

Advanced Options

Options

You can add these to options/directly to the ping property in the above example if you dont want them to be polymer reactive.

  • skip Used to set the state of the query subscribtion. Check example below.
  • loadingKey will update the component data property you pass as the value. You should initialize this property to false in properties. When the query is loading, this property will be set to true and as soon as it no longer is, the property will be set to false.
Hooks

These are the available advanced options you can use:

  • error(error) is a hook called when there are errors, error being an Apollo error object with either a graphQLErrors property or a networkError property.
  • success(result) is a hook called when query/subscription returns successfully. Note. result = { data, loading, networkStatus}
  • watchLoading(isLoading) is a hook called when the loading state of the query changes.
...
static get properties() {
  return {
    computedProp: {
      type: Object,
      computed: 'computeFn(prop1, prop2)'
    }
  };
}
// Apollo-specific options
get apollo() {
  return {
  // Advanced query with parameters
  pingMessage: {
    query: gql`query PingMessage($message: String!) {
      ping(message: $message)
    }`,
    // Reactive parameters
    options: 'computedProp',

    // Loading state
    // loadingKey is the name of the data property
    // that will be unset when the query is loading
    // and set when it no longer is.
    loadingKey: 'loadingQueriesCount',
    // Error handling
    error(error) {
      console.error('We\'ve got an error!', error);
    },
    success(result) {
      console.error('Success.!', result); // result is of the format { data, loading, networkStatus };
    },
    // watchLoading will be called whenever the loading state changes
    watchLoading(isLoading) {
      // isLoading is a boolean
    },
  },
  };
}
computedFn: function(prop1, prop2) {
  return { variables: { message: `${prop1} ping...`}, skip: prop2 };
}

Refetch Query

Use $apollo.refetch(key);

<paper-icon-button on-tap="refetchTags" icon="refresh"></paper-icon-button>
// Apollo-specific options
{
  // 'tags' property of your polymer element
  tags: {
    query: gql`query tagList {
      tags {
        id,
        label
      }
    }`,
  },
},
refetchTags(){
   this.$apollo.refetch("tags");
}

Reactive Query Example

Here is a reactive query example using polling:

...
static get properties() {
  return {
    computedProp: {
      type: Object,
      computed: 'computeFn(prop1, prop2)'
    }
  };
}
// Apollo-specific options
get apollo() {
  return {
  // 'tags' property of your polymer element
  tags: {
    query: gql`query tagList {
      tags {
        id,
        label
      }
    }`,
    options: 'computedProp',
  },
  };
}
computedFn: function(prop1, prop2) {
  return {
    variables: { var1: prop1 },
    pollInterval: prop2, // ms
  };
}

Here is how the server-side looks like:

export const schema = `
type Tag {
  id: Int
  label: String
}

type Query {
  tags: [Tag]
}

schema {
  query: Query
}
`;

// Fake word generator
import casual from 'casual';

// Let's generate some tags
var id = 0;
var tags = [];
for (let i = 0; i < 42; i++) {
  addTag(casual.word);
}

function addTag(label) {
  let t = {
    id: id++,
    label,
  };
  tags.push(t);
  return t;
}

export const resolvers = {
  Query: {
    tags(root, args, context) {
      return tags;
    },
  },
};

Skip query example

...
static get properties() {
  return {
    computedProp: {
      type: Object,
      computed: 'computeFn(prop1, prop2)'
    }
  };
}

// Apollo-specific options
get apollo() {
  return {
  // 'tags' property of your polymer element
  tags: {
    query: gql`query tagList {
      tags {
        id,
        label
      }
    }`,
    options: 'computedProp',
  },
  };
}
computedFn: function(prop1, prop2) {
  return {
    variables: { var1: prop1 },
    skip: prop2, // Boolean
  };
}

Fragments

import gql from 'graphql-tag';

const fragment = gql`fragment CommonFields on tags {
  id,
  label
}`;

Embed the fragment in your query document directly with:

import gql from 'graphql-tag';
// Apollo-specific options
return {
  // 'tags' property of your polymer element
  tags: {
    query: gql`query tagList {
      tags: tags(rate: 0) {
        ...CommonFields
      },
      besttags: tags(rate: 10) {
        ...CommonFields
      }
    }
    ${fragment}`
  },
}

Mutations

Mutations are queries that changes your data state on your apollo server. For more info, visit the apollo doc.

  addTag() {
    // We save the user input in case of an error
    const newTag = this.newTag;
    // We clear it early to give the UI a snappy feel
    this.newTag = '';
    // Call to the graphql mutation
    this.$apollo.mutate({
      // Query
      mutation: gql`mutation ($label: String!) {
        addTag(label: $label) {
          id
          label
        }
      }`,
      // Parameters
      variables: {
        label: newTag,
      },
      // Update the cache with the result
      // 'tagList' is the name of the query declared before
      // that will be updated with the optimistic response
      // and the result of the mutation
      updateQueries: {
        tagList: (previousQueryResult, { mutationResult }) => {
          // We incorporate any received result (either optimistic or real)
          // into the 'tagList' query we set up earlier
          return {
            tags: [...previousQueryResult.tags, mutationResult.data.addTag],
          };
        },
      },
      // Optimistic UI
      // Will be treated as a 'fake' result as soon as the request is made
      // so that the UI can react quickly and the user be happy
      optimisticResponse: {
        __typename: 'Mutation',
        addTag: {
          __typename: 'Tag',
          id: -1,
          label: newTag,
        },
      },
    }).then((data) => {
      // Result
      console.log(data);
    }).catch((error) => {
      // Error
      console.error(error);
      // We restore the initial user input
      this.set("newTag",newTag);
    });
  },
},

Server-side:

export const schema = `
type Tag {
  id: Int
  label: String
}

type Query {
  tags: [Tag]
}

type Mutation {
  addTag(label: String!): Tag
}

schema {
  query: Query
  mutation: Mutation
}
`;

// Fake word generator
import faker from 'faker';

// Let's generate some tags
var id = 0;
var tags = [];
for (let i = 0; i < 42; i++) {
  addTag(faker.random.word());
}

function addTag(label) {
  let t = {
    id: id++,
    label,
  };
  tags.push(t);
  return t;
}

export const resolvers = {
  Query: {
    tags(root, args, context) {
      return tags;
    },
  },
  Mutation: {
    addTag(root, { label }, context) {
      console.log(`adding tag '${label}'`);
      return addTag(label);
    },
  },
};

Subscriptions

To make enable the websocket-based subscription, a bit of additional setup is required:

import ApolloClient, { createNetworkInterface } from 'apollo-client';
// New Imports
import { Client } from 'subscriptions-transport-ws';
import { print } from 'graphql-tag/printer';

// quick way to add the subscribe and unsubscribe functions to the network interface
const addGraphQLSubscriptions = (networkInterface, wsClient) => Object.assign(networkInterface, {
  subscribe: (request, handler) => wsClient.subscribe({
    query: print(request.query),
    variables: request.variables,
  }, handler),
  unsubscribe: (id) => {
    wsClient.unsubscribe(id);
  },
});

// Create the network interface
const networkInterface = createNetworkInterface({
  uri: 'http://localhost:3000/graphql',
  transportBatching: true,
});

// Create the subscription websocket client
const wsClient = new Client('ws://localhost:3030');

// Extend the network interface with the subscription client
const networkInterfaceWithSubscriptions = addGraphQLSubscriptions(
  networkInterface,
  wsClient,
);

// Create the apollo client with the new network interface
export const apolloClient = new ApolloClient({
  networkInterface: networkInterfaceWithSubscriptions,
});

// Your app is now subscription-ready!

Use the $apollo.subscribe() method to subscribe to a GraphQL subscription that will get killed automatically when the component is detached. To disable this feature set onReady = true. :

attached() {
  const subQuery = gql`subscription tags($type: String!) {
    tagAdded(type: $type) {
      id
      label
      type
    }
  }`;

  const observer = this.$apollo.subscribe({
    query: subQuery,
    variables: {
      type: 'City',
    },
  });

  observer.subscribe({
    next(data) {
      console.log(data);
    },
    error(error) {
      console.error(error);
    },
  });
},

You can declare subscriptions in the apollo option with the subscribe keyword:

static get properties() {
  return {
    cityComputed: {
      type: Object,
      computed: 'getCity(city)'
    }
  };
}
get apollo() {
  return {
  // Subscriptions
  subscribe: {
    // When a tag is added
    tags: {
      query: gql`subscription tags($type: String!) {
        tagAdded(type: $type) {
          id
          label
          type
        }
      }`,
      options: 'cityComputed',
      // Reactive variables

      // Success hook
      success(data) {
        console.log(data);
        // Let's update the local data
        this.tags.push(data.tagAdded);
      },
    },
  },
  };
}
getCity(city) {
    return {
      variables: {
        // This works just like regular queries
        // and will re-subscribe with the right variables
        // each time the values change
        type: city,
      },
    };
}

You can then access the subscription ObservableQuery object with this.$apollo.subscriptions.<name>.

Pagination with fetchMore

Use the fetchMore() method on the query:

<template>
  <div>
    <h2>Pagination</h2>
    <div class="tag-list" hidden="{{!tagsPage}}">
      <template is="dom-repeat" items="[[tagsPage.tags]]" as="tag">
        <div class="tag-list-item">
          {{ tag.id }} - {{ tag.label }} - {{ tag.type }}
        </div>
      </template>
      <div class="actions">
        <paper-button hidden="{{!showMoreEnabled}}" on-tap="showMore">Show more</paper-button>
      </div>
    </div>
  </div>
</template>

<script>
import { PolymerApolloMixin } from 'polymer-apollo';
import { apolloClient } from './config.js';
import gql from 'graphql-tag';

class MyElement extends PolymerApolloMixin({apolloClient}, Polymer.Element) {
  static get is() {
    return 'example-element'
  }
  static get properties() {
    return {
      page: {
        type: Number,
        value: 0,
      },
      pageSize: {
        type: Number,
        value: 10,
      },
      showMoreEnabled: {
        type: Number,
        value: true,
      },
    }
  }
  get apollo() {
    return {
    // Pages
    tagsPage: {
      // GraphQL Query
      query: gql`query tagsPage ($page: Int!, $pageSize: Int!) {
        tagsPage(page: $page, size: $pageSize) {
          tags {
            id
            label
            type
          }
          hasMore
        }
      }`,
      options: {
        // Initial variables
        variables: {
          page: 'page',
          pageSize: 'pageSize',
        },
      },

    },
    };
  }
  showMore() {
    this.page ++;
    // Fetch more data and transform the original result
    this.$apollo.queries.tagsPage.fetchMore({
      // New variables
      variables: {
        page: this.page,
        pageSize: 20,
      },
      // Transform the previous result with new data
      updateQuery: (previousResult, { fetchMoreResult }) => {
        const newTags = fetchMoreResult.data.tagsPage.tags;
        const hasMore = fetchMoreResult.data.tagsPage.hasMore;

        this.showMoreEnabled = hasMore;

        return {
          tagsPage: {
            // Merging the tag list
            tags: [...previousResult.tagsPage.tags, ...newTags],
            hasMore,
          },
        };
      },
    });
  }
};
</script>

Similar to fetchMore the following methods can be used. for queries $apollo.queries[name] for subscriptions $apollo.subscriptions[name]

  • refetch()
  • fetchMore()
  • updateQuery()
  • startPolling()
  • stopPolling()
  • subscribeToMore()
  • currentResult()
  • variables : an object containing variables used to get this result.
  • loading : boolean, useful if you set notifyOnNetworkStatusChange to true in query options.
  • networkStatus : the status of the request ,useful if you set notifyOnNetworkStatusChange to true in query options

Like it?

โญ this repo

Found a bug?

Raise an issue!

Contributors

Anthony Hinsinger (@atoy40)

Arun Kumar T K (@aruntk)

Edward Watson (@edge0701)

polymer-apollo's People

Contributors

aruntk avatar atoy40 avatar edge0701 avatar james-damstra avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polymer-apollo's Issues

from-scratch rewriting

hello, @aruntk
Just to tell you I've reimplemented some ideas from scratch, because i've some difficulties to update your code (not easy to add a new functionnality without breaking an old one)
It's here, take a look and tell me :
https://github.com/atoy40/kapton

It's a very early publishing. It's inspired by the react-apollo package. In term of main functionnality, I've to add subscriptions, but nothing difficult.

Anthony.

Cannot pass headers

I was trying to pass auhtorization headers, but it doesn't work.

var networkInterface = createNetworkInterface({
  uri: 'http://buurb.core.local/api/v1/graphql',
  opts: {
    headers: {
      'Authorization': 'Bearer wzTvclDTOA1EpRcsROLP_yo2risS0v5C',
    }
  }
});

Reusing a component

Hi there,

I'm having trouble getting it to work properly, I have the following configuration for my element, seems pretty simple:

This binds the resulting object to the pageObject property of the element. This is great, but this seems me to require to name the query pageObject: Page(id: $identifier) { ... }. The result is that if I use this element multiple times, this will cause an issue that the the second element will use the same query name, thus breaking the first element..

Hope you can help:

  • I'm not exactly sure why I need to provide a name for the query in the first place, shouldn't the Apollo client handle this for me? It needs to batch multiple queries, etc...
  • The name of the first query object in the apollo object PageLink in this example serves no purpose at all, just needs to be unique (globally?). Ideally this would mean it would be bound to that property?
<dom-module id="rd-page-link">
  <template>
    <a href$="[[pageObject.urlKey]]"><content></content></a>
  </template>
  <script>
    Polymer({
      is: "rd-page-link",

      properties: {
        pageId: String,
        pageObject: Object,
        href: {
          type: String,
          computed: '_getHref(pageObject)'
        }
      },
      behaviors: [
        Apollo.PolymerBehavior,
      ],

      apollo: {
        PageLink: {
          query: Apollo.gql`query GetPageLink($identifier: ID!) {
                    pageObject: Page(id: $identifier) {
                      title,
                      urlKey
                    }
                  }`,
          options: '_queryOptions(pageId)',
          loadingKey: 'hostLoading',
        }
      },

      _queryOptions: function(pageId) {
        return {
          variables: {
            identifier: pageId
          },
        };
      },

      _getHref: function(pageObject) {
        console.log(pageObject);
        return pageObject.urlKey;
      },

    })
  </script>
</dom-module>

Polymer 2.0 mixin

I'm looking at PolymerApollo right now, trying to convert your behavior to 2.0 syntax. Some things to discuss are:

  • Where to put beforeRegister stuff? This has been removed with 2.x, I think this might belong into the constructor now (2.0 is class based like standard webcomponents)
  • How do we create the PolymerApollo behavior?

I was thinking doing it like so:

export const PolymerApollo = (superclass, options) => class extends superclass {

And then in the component do this maybe?

class AppShell extends PolymerApolloBehavior(Polymer.Element, apolloClient) {

Please let me know what you think, I'm just learning classes now, so I'm not sure if that makes sense.

Almost got something working, just gotta fix some dependencies in a demo, then I'll push a sample repo with what I have so far.

Automatically define property values as variables

I have for example the following (simplified) element:

<script>
  Polymer({
    is: "rd-page-link",

    properties: {
      pageId: String,
      pageObject: Object
    },

    apollo: {
      PageLink: {
        query: Apollo.gql`query GetPageLink($identifier: ID!) {
                    pageObject: Page(id: $identifier) {
                      title,
                      urlKey
                    }
                  }`,
        options: '_queryOptions(pageId)',
      }
    },

    _queryOptions: function (pageId) {
      return {
        variables: {
          identifier: pageId
        },
      };
    },

  })
</script>

Wouldn't it be nice if you didn't have to define the link between the GraphQL variable $identifier and the polymer property pageId. Would be nice if the following just worked.

<script>
  Polymer({
    is: "rd-page-link",

    properties: {
      pageId: String,
      pageObject: Object
    },

    apollo: {
      PageLink: {
        query: Apollo.gql`query GetPageLink($pageId: ID!) {
                    pageObject: Page(id: $pageId) {
                      title,
                      urlKey
                    }
                  }`,
      }
    },

  })
</script>

And to move further, would be nice if we didn't need the key in the apollo object, doesn't serve any purpose?

<script>
  Polymer({
    is: "rd-page-link",

    properties: {
      pageId: String,
      pageObject: Object
    },

    apollo: [{
      query: Apollo.gql`query GetPageLink($pageId: ID!) {
            pageObject: Page(id: $pageId) {
              title,
              urlKey
            }
          }`,
    }],

  })
</script>

Problem with polymer-apollo babel output ?

Hello, i'm trying tu use your project on a polymer/graphql application i'm working on, and i've a problem
I've "webpacked" my js code andload it into the browser with a script tag, but when it's loaded, i get a :

_polymerApollo2.default is not a constructor

Maybe this part of the webpack output can help you to help me :) :

    var _apolloClient = __webpack_require__(2);

    var _apolloClient2 = _interopRequireDefault(_apolloClient);

    var _polymerApollo = __webpack_require__(65);

    var _polymerApollo2 = _interopRequireDefault(_polymerApollo);

    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

    // Create the apollo client
    var apolloClient = new _apolloClient2.default({
      networkInterface: (0, _apolloClient.createNetworkInterface)({
        uri: 'http://localhost:8080/graphql',
        transportBatching: true
      }),
      queryTransformer: _apolloClient.addTypename
    });

    //create a new polymer behavior from PolymerApollo class. 
    PolymerApolloBehavior = new _polymerApollo2.default({ apolloClient: apolloClient });

I've used the chromium debbuger, and it seems _polymerApollo2 has no property "default". A problem with the "babelisation" done at npm install ? (apollo-client class own a default property and constructs well)

thks, and don't hesitate to ask me more informations :)

Refresh a query

Hello,

i've a polymer element with the PolymerApolloBehavior, and want to know if it's possible to "refresh" a query result either through code (calling a function on $apollo ?) or through a polymer binding ?
My query has no variable so I cannot use your "observers" mechanisme on variables and I don't want to use polling.

Thks
Anthony.

Bug in catchError functions

Hello, in catchError functions, you use ${query} in console.error calls, but query is not defined.
May be ${key} is the one to use ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.