Apollo-link: subscribe is not a function

Created on 30 Oct 2017  ·  2Comments  ·  Source: apollographql/apollo-link

Hi,

I'm trying to use apollo-link in react native

here's my current client setup code.

import React, { Component } from 'react';
import { AsyncStorage } from 'react-native';
import { ApolloClient } from 'apollo-client';
import { createHttpLink } from 'apollo-link-http';
import { ApolloLink } from 'apollo-link';
import {
  InMemoryCache,
  IntrospectionFragmentMatcher
} from 'apollo-cache-inmemory';
import { ApolloProvider } from 'react-apollo';
import fragmentTypes from './data/fragmentTypes';

import Application from './scenes/Application';

const httpLink = createHttpLink({ uri: 'http://10.0.1.5:3000/graphql' });

const authMiddleware = new ApolloLink(async (operation, forward) => {
  const token = await AsyncStorage.getItem('token');
  operation.setContext({
    headers: {
      authorization: token
    }
  });
  return forward(operation);
});

const link = authMiddleware.concat(httpLink);

const cache = new InMemoryCache({
  fragmentMatcher: new IntrospectionFragmentMatcher({
    introspectionQueryResultData: fragmentTypes
  })
});

const client = new ApolloClient({
  link,
  cache
});

and here's the error I'm getting.

Unhandled (in react-apollo) Error: Network error: _this.inFlightRequestObservables[key].subscribe is not a function
    at new ApolloError (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:95440:32)
    at ObservableQuery.currentResult (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:95548:28)
    at GraphQL.dataForChild (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:101809:66)
    at GraphQL.render (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:101860:37)
    at finishClassComponent (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:9022:112)
    at updateClassComponent (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:9015:338)
    at beginWork (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:9121:28)
    at performUnitOfWork (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:10032:24)
    at workLoop (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:10051:125)
    at Object._invokeGuardedCallback (http://localhost:19001/node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=ios&dev=true&strict=false&minify=false&hot=false&assetPlugin=/Users/aaronreisman/Workspace/lifeiscontent/app/node_modules/expo/tools/hashAssetFiles:7144:18)
reactConsoleErrorHandler @ ExceptionsManager.js:73
console.error @ YellowBox.js:69
(anonymous) @ react-apollo.browser.umd.js:547
(anonymous) @ JSTimers.js:256
_callTimer @ JSTimers.js:148
callTimers @ JSTimers.js:405
__callFunction @ MessageQueue.js:306
(anonymous) @ MessageQueue.js:108
__guard @ MessageQueue.js:269
MessageQueue.callFunctionReturnFlushedQueue @ MessageQueue.js:107
(anonymous) @ debuggerWorker.js:72

Most helpful comment

Hi @lifeiscontent
I was facing similar error, as far as i know It is occurred due to new ApolloLink(async (operation, forward) => {,
after removing async it works fine for me.
To implement async functions, here is my attempt

const authMiddleware = new ApolloLink(
  (operation, forward) =>
    new Observable(observer => {
      AsyncStorage.getItem('token')
        .then(token => {
           operation.setContext({
            headers,
          });
        })
        .then(() => {
          const subscriber = {
            next: observer.next.bind(observer),
            error: observer.error.bind(observer),
            complete: observer.complete.bind(observer),
          };
          forward(operation).subscribe(subscriber);
        })
        .catch(err => {
          observer.error(err);
        });
    })
);

All 2 comments

Hi @lifeiscontent
I was facing similar error, as far as i know It is occurred due to new ApolloLink(async (operation, forward) => {,
after removing async it works fine for me.
To implement async functions, here is my attempt

const authMiddleware = new ApolloLink(
  (operation, forward) =>
    new Observable(observer => {
      AsyncStorage.getItem('token')
        .then(token => {
           operation.setContext({
            headers,
          });
        })
        .then(() => {
          const subscriber = {
            next: observer.next.bind(observer),
            error: observer.error.bind(observer),
            complete: observer.complete.bind(observer),
          };
          forward(operation).subscribe(subscriber);
        })
        .catch(err => {
          observer.error(err);
        });
    })
);

@AnujKosambi I actually got it to work. You can see my example here:

import { AsyncStorage } from 'react-native';
import {
  InMemoryCache,
  IntrospectionFragmentMatcher
} from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { onError } from 'apollo-link-error';
import { setContext } from 'apollo-link-context';
import fragmentTypes from './data/fragmentTypes';

const httpLink = new HttpLink({ uri: '/graphql' });

let token;

const withToken = setContext(async request => {
  if (!token) {
    token = await AsyncStorage.getItem('token');
  }
  return {
    headers: {
      authorization: token
    }
  };
});

const resetToken = onError(({ networkError }) => {
  if (networkError && networkError.statusCode === 401) {
    // remove cached token on 401 from the server
    token = undefined;
  }
});

const authFlowLink = withToken.concat(resetToken);

const link = authFlowLink.concat(httpLink);

const cache = new InMemoryCache({
  fragmentMatcher: new IntrospectionFragmentMatcher({
    introspectionQueryResultData: fragmentTypes
  })
});

export default new ApolloClient({
  link,
  cache
});
Was this page helpful?
0 / 5 - 0 ratings