Skip to content

Instantly share code, notes, and snippets.

@du5rte
Last active Feb 26, 2017
Embed
What would you like to do?
GraphQL Subscriptions
import React, { Component, PropTypes } from 'react';
import { graphql } from 'react-apollo'
import gql from 'graphql-tag'
import update from 'immutability-helper'
import { Toggler, colors } from "./Toggler"
import View from "react-flexbox"
@graphql(gql`
query togglerQuery {
toggler
}
`)
@graphql(gql`
mutation togglerMutation($value: Boolean!) {
toggler(value: $value)
}
`,{
props: ({ ownProps, mutate }) => ({
toggle: (value) => mutate({
variables: {
value
},
updateQueries: {
togglerQuery: (prev, { mutationResult }) => update(prev, {
toggler: {$set: mutationResult.data.toggler}
})
}
})
})
})
export default class Render extends Component {
componentWillReceiveProps(newProps) {
if (!newProps.data.loading) {
if (this.subscription) {
if (newProps.data.feed !== this.props.data.feed) {
// if the feed has changed, we need to unsubscribe before resubscribing
this.subscription.unsubscribe();
} else {
// we already have an active subscription with the right params
return;
}
}
// const entryIds = newProps.data.feed.map(item => item.id)
this.subscription = newProps.data.subscribeToMore({
document: gql`
subscription togglerSubscription {
toggler
}
`,
variables: {},
// this is where the magic happens.
updateQuery: (prev, {subscriptionData}) => {
console.log('😱')
return prev; // Modify your store and return new state with the new arrived data
},
onError: (err) => console.error(err),
})
}
}
handleToggle(e) {
this.props.toggle(!this.props.data.toggler)
.then(({ data }) => {
// this.props.data.refetch()
}).catch((error) => {
console.log(error)
})
}
render() {
const style = {
justifyContent: 'center',
alignItems: 'center',
height: '100vh',
fontSize: '10vw',
background: this.props.data.toggler ? colors.green : colors.red,
}
return (
<View style={style}>
<Toggler value={this.props.data.toggler} onClick={this.handleToggle.bind(this)} />
</View>
)
}
}
import {
GraphQLBoolean,
GraphQLNonNull,
GraphQLObjectType
} from 'graphql'
let toggleValue = false
import { pubsub } from "../../subscriptionManager"
export const TogglerType = new GraphQLNonNull(GraphQLBoolean)
export const togglerQuery = {
type: TogglerType,
description: "0 or 1, false or true",
resolve(root, args, ctx, info) {
return toggleValue
}
}
export const togglerMutation = {
type: TogglerType,
description: "Perceptions of truth are relative, choose yours",
args: {
value: {
type: new GraphQLNonNull(GraphQLBoolean),
description: "0 or 1, false or true"
}
},
resolve(root, args, ctx, info) {
return Promise.resolve()
.then(() => {
toggleValue = args.value
return toggleValue
})
.then((value) => {
// publish subscription notification
pubsub.publish("togglerChannel", value)
return value
})
}
}
const togglerSubscription = {
type: TogglerType,
description: "Are you ready for the truth?",
resolve(root, args, ctx, info) {
return sourceOfTruth
}
}
export default new GraphQLSchema({
query: new GraphQLObjectType({
name: 'Queries',
fields: () => ({
togglerQuery
})
}),
mutation: new GraphQLObjectType({
name: 'Mutations',
fields: () => ({
togglerMutation
})
}),
subscription: new GraphQLObjectType({
name: 'Subscriptions',
fields: () => ({
togglerSubscription
})
})
})
import { SubscriptionManager, PubSub } from 'graphql-subscriptions'
import schema from "./schema"
const pubsub = new PubSub()
const subscriptionManager = new SubscriptionManager({
schema,
pubsub,
setupFunctions: {},
})
pubsub.publish("togglerChannel", false)
pubsub.subscribe("togglerChannel", function(data){
console.log(data)
})
export { subscriptionManager, pubsub }
import { createServer } from 'http';
import { SubscriptionServer } from 'subscriptions-transport-ws';
import { subscriptionManager } from './subscriptionManager'
// start a subscription
subscriptionManager.subscribe({
query: `
subscription togglerSubscription {
toggler
}
`,
variables: {},
context: {},
callback: (err, data) => console.log(err, data),
})
const WS_PORT = 5000;
// Create WebSocket listener server
const websocketServer = createServer((request, response) => {
response.writeHead(404);
response.end();
});
// Bind it to port and start listening
websocketServer.listen(WS_PORT, () => console.log(
`Websocket Server is now running on ws:${WS_PORT}`
));
const subscriptionServer = new SubscriptionServer({
onConnect: async (connectionParams) => {
// Implement if you need to handle and manage connection
console.log("connected")
},
subscriptionManager: subscriptionManager
},{
server: websocketServer,
path: '/'
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment