So I'm attempting to stitch multiple remote GraphCMS endpoints together on the clientside of a Next.js app, and after trying/combining about every example on the face of the internet, I've gotten it to a place that's worth asking about. My error:
TypeError: this.getClient(...).watchQuery is not a function at GraphQL.createQuery
github repo here, where you can see this initApollo.js in context:
import { ApolloClient } from 'apollo-client'import {
makeRemoteExecutableSchema,
mergeSchemas,
introspectSchema
} from 'graphql-tools'import { HttpLink } from 'apollo-link-http'import { InMemoryCache } from 'apollo-cache-inmemory'import fetch from 'node-fetch'import { Observable, ApolloLink } from 'apollo-link'import { graphql, print } from 'graphql'import { createApolloFetch } from 'apollo-fetch'let apolloClient = nullif (!process.browser) {
global.fetch = fetch
}
const PRIMARY_API = 'https://api.graphcms.com/simple/v1/cjfipt3m23x9i0190pgetwf8c'const SECONDARY_API = 'https://api.graphcms.com/simple/v1/cjfipwwve7vl901427mf2vkog'const ALL_ENDPOINTS = [PRIMARY_API, SECONDARY_API]
async function createClient (initialState) {
const AllLinks = ALL_ENDPOINTS.map(endpoint => {
return new HttpLink({
uri: endpoint,
fetch
})
})
const allSchemas = []
for (let link of AllLinks) {
try {
allSchemas.push(
makeRemoteExecutableSchema({
schema: await introspectSchema(link),
link
})
)
} catch (e) {
console.log(e)
}
}
const mergedSchema = mergeSchemas({
schemas: allSchemas
})
const mergedLink = operation => {
return new Observable(observer => {
const { query, variables, operationName } = operation
graphql(mergedSchema, print(query), {}, {}, variables, operationName)
.then(result => {
observer.next(result)
observer.complete()
})
.catch(e => observer.error(e))
})
}
return new ApolloClient({
connectToDevTools: process.browser,
ssrMode: !process.browser,
link: mergedLink,
cache: new InMemoryCache().restore(initialState || {})
})
}
export default function initApollo (initialState) {
if (!process.browser) {
return createClient(initialState)
}
if (!apolloClient) {
apolloClient = createClient(initialState)
}
console.log('\x1b[37m%s\x1b[0m', apolloClient)
return apolloClient
}
I'm getting useful data all the way up into the .then() inside the Observable, where I can log the result
It looks like the issue is with the mergedLink that you are passing to the ApolloClient. The mergedLink function returns an Observable object, but ApolloClient expects an ApolloLink object.
To fix this, you can use the from function from the apollo-link package to convert the Observable to an ApolloLink. You can do this like this:
import { from } from 'apollo-link'; const mergedLink = from(operation => { return new Observable(observer => { const { query, variables, operationName } = operation graphql(mergedSchema, print(query), {}, {}, variables, operationName) .then(result => { observer.next(result) observer.complete() }) .catch(e => observer.error(e)) }) });
With this change, the mergedLink variable will now be an ApolloLink object that can be passed to the ApolloClient.